这个变量的长度是多少(IF语句)

时间:2015-11-24 14:05:04

标签: sas

以下是代码:

data test;
   set sasdata.chemist(keep=job_code);
   if job_code = 'chem3'
   then description = 'Senior Chemist';
run;

变量job_code是一个长度为6个字节的字符变量。那么,输出数据集中变量描述的长度是多少?据我所知,描述变量仍然缺失,因为if语句的计算结果为false。因此,长度为0.但正确的答案是14个字节。为什么14?有谁可以向我解释一下?非常感谢您的时间和关注。

修改 由于以下代码也与变量的长度有关,因此将它组合在一起是有意义的。

data work.test;
  Author = 'Agatha Christie';
  First = substr(scan(author, 1, ','),1,1);
run;

所以变量的长度' First'根据答题纸是200。我知道变量长度是在编译时确定的。不过,为什么是200?任何评论将不胜感激。

PS。有了java,python,r和matlab的经验,我觉得SAS与其他人相比有点奇怪。我非常感谢你的所有评论,无论它是什么。当然,我特别欣赏所有的鼓励,这真的让我的一天更加美好。我会读更多,并尽量不要提出琐碎的问题。

3 个答案:

答案 0 :(得分:3)

或许比汤姆的答案更详细一点。

当SAS流程收到数据步骤的代码时,它会经历可以被认为是三个不同阶段的过程。

  • 宏解析
  • 汇编
  • 执行

在所有实例中都不需要进行宏解析,但它仍会先检查是否有任何宏标记(包含%&的内容)进行解析。

然后,它通过编译阶段。这就是SAS确定数据步骤将要做什么的地方。在处理任何数据之前,SAS知道:

  • 输入数据集是什么
  • 输出数据集是什么
  • 输入数据集中有哪些变量
  • 需要在PDV中定义哪些变量 - 在处理期间存储数据
  • 将输出哪些变量到输出数据集
  • 变量的长度
  • 变量的格式是什么,并且
  • 变量的顺序

......还有很多其他信息。所有这些都是在读取任何数据之前确定的。来自输入数据集的信息在数据集的前几个块中可用(基本上,PROC CONTENTS能够生成的任何内容都存储在那里)。在读取任何数据之前,所有内容都已读取,然后计算出来。

然后读取数据,并在执行阶段执行if语句之类的操作。

这就是为什么你不能在IF块中改变变量的长度,或者保留或删除哪些变量的长度,或变量的格式。编译阶段所做的一切都取决于数据:所有这些都是事先知道

相反,当SAS在数据步骤中看到新变量时,它会做什么,它会立即在PDV中为它创建一个新条目。它查看代码并决定制作它的时间,给它一个默认格式,标签等。一旦它被创建(在第一次遇到之后),它甚至不会改变任何这些东西如果以后再看到它。

因此,例如,在此代码中:

data test;
  x="Hello";
  output;
  x="Goodbye";
  output;
run;

您认为test是什么?

以下内容:

_N_=1 x=Hello
_N_=2 x=Goodb

是的。你丢失了几个字符,因为SAS基于x的第一个实例使它长5。您当然可以自己定义长度,或者切换这些语句的顺序,并获得不同的结果。

然后,如果你写:

data test;
  if 0 then x='Hello';
  if 1 then x='Goodbye';
  output;
run;

你现在会得到什么?

答案:

_N_=1 x=GOODB

SAS编译器看到了第一行,尽管很明显if 0是假的,但它并不关心:它仍然会做同样的事情。它总是这样。它看到x='Hello',在PDV上创建一个x变量。然后执行阶段,它实际上处理if语句;因此,只创建/输出第二行。但它仍然只有5长!

我建议在这里阅读一些核心SAS文档,尤其是Introduction to DATA Step processing。关于这个问题,也有不少好的论文(和书籍);搜索术语除了" SAS数据步骤"是" PDV" (节目数据向量)和"编译" vs"执行"。

答案 1 :(得分:2)

SAS会尽快定义变量的类型和长度。它将根据它所看到的代码的最佳猜测来设置长度。它在步骤开始执行之前编译数据步骤期间执行此操作。

在您的情况下,description的第一个引用位于赋值语句中。由于它被分配了一个14字节长的字符串,因此将变量定义为长度为14的字符。

job_code的第一个引用位于SET语句中。 SAS将创建job_code以匹配源数据集中的定义方式。这就是为什么它被定义为长度6而不是被定义为长度5以匹配'chem3'的长度。

如果对变量的第一次引用是字符函数结果的赋值,则SAS通常默认为$ 200。

如果您想确定如何定义变量,请在使用其他语句之前使用LENGTHATTRIB语句明确定义它们。

您似乎也混淆了变量的特定值的长度和变量的已定义的最大长度。 SAS将字符变量存储为固定长度。当你谈到变量的长度时,通常意味着这个定义的最大长度。当您为变量分配较短的值时,它会用空格填充以填充空格。

您可以使用LENGTH()函数计算存储在字符变量(或字符串文字)中的值的长度。长度是字符串中最后一个非空字符的位置。另请注意,按照惯例,所有空白字符串的长度为1.如果您希望将所有空白字符串视为长度为0,则可以使用LENGTHN()函数。

答案 2 :(得分:0)

因为变量的长度将在编译时分配,而不是在运行时分配。当代码编译时,它将编译所有步骤,而不仅仅是条件为真时的步骤。

因此,在这种情况下,长度被指定为存储文本所需的长度'高级化学家',这是14