对SAS的疑问:
data new;
set _NULL_;
run;
data _NULL_;
set new;
if _N_ = 0 then call execute ("%put empty dataset;");
if _N_ = 1 then call execute ("%put non-empty dataset;");
run;
我理解的上述代码应该只打印第一个注释,即空数据集。出于某种原因,虽然它也为第二个if条件返回true并且也打印非空数据集。
请告诉我这里哪里出错?
答案 0 :(得分:10)
好的,这就是我的想法。第一个问题是您的宏调用是双引号,因此在SAS甚至开始处理数据步骤之前由预处理器处理(无论if条件是否为真,都执行)。您需要将参数放在单引号而不是双引号中,以防止它被宏预处理器过早执行。
此代码仍无法在空数据集上运行,但是,如果设置行上提供的数据集为空,则在执行任何其他代码之前,整个数据步骤将终止。
第三,_N_初始化为1而不是0,并在数据步边界处从那里递增,因此_N_ = 0
条件将始终为假。
另一种解决方法是使用nobs =选项设置如下:
data _NULL_;
if 0 then set new nobs=num_obs;
if num_obs = 0 then call execute ('%put empty dataset;');
if num_obs > 0 then call execute ('%put non-empty dataset;');
stop;
run;
if 0 then
是用于强制执行数据步骤代码的虚拟条件;如果使用了裸集语句,那么如果数据集“new”为空,执行将不会继续超过设定行。
更好的选择可能是使用宏来打开数据集并读取ANY属性:
%let dsid = %sysfunc (open(dataset_name));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid = %sysfunc (close(&dsid));
如果dataset_name包含至少一个观察(行)和至少一个变量(列),则宏变量&anyobs
将为1,如果它不包含任何观察但至少包含一个变量,则为0,如果包含,则为-1不包含任何观察结果,也没有变量。