如果_N_ = 1条件返回true,即使SAS中的设置数据集为空(零观察)

时间:2011-10-11 15:31:59

标签: null dataset sas

对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并且也打印非空数据集。

请告诉我这里哪里出错?

1 个答案:

答案 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不包含任何观察结果,也没有变量。