以下是代码:
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与其他人相比有点奇怪。我非常感谢你的所有评论,无论它是什么。当然,我特别欣赏所有的鼓励,这真的让我的一天更加美好。我会读更多,并尽量不要提出琐碎的问题。
答案 0 :(得分:3)
或许比汤姆的答案更详细一点。
当SAS流程收到数据步骤的代码时,它会经历可以被认为是三个不同阶段的过程。
在所有实例中都不需要进行宏解析,但它仍会先检查是否有任何宏标记(包含%
或&
的内容)进行解析。
然后,它通过编译阶段。这就是SAS确定数据步骤将要做什么的地方。在处理任何数据之前,SAS知道:
......还有很多其他信息。所有这些都是在读取任何数据之前确定的。来自输入数据集的信息在数据集的前几个块中可用(基本上,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。
如果您想确定如何定义变量,请在使用其他语句之前使用LENGTH
或ATTRIB
语句明确定义它们。
您似乎也混淆了变量的特定值的长度和变量的已定义的最大长度。 SAS将字符变量存储为固定长度。当你谈到变量的长度时,通常意味着这个定义的最大长度。当您为变量分配较短的值时,它会用空格填充以填充空格。
您可以使用LENGTH()
函数计算存储在字符变量(或字符串文字)中的值的长度。长度是字符串中最后一个非空字符的位置。另请注意,按照惯例,所有空白字符串的长度为1.如果您希望将所有空白字符串视为长度为0,则可以使用LENGTHN()
函数。
答案 2 :(得分:0)
因为变量的长度将在编译时分配,而不是在运行时分配。当代码编译时,它将编译所有步骤,而不仅仅是条件为真时的步骤。
因此,在这种情况下,长度被指定为存储文本所需的长度'高级化学家',这是14