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

AP-*_*AP- 5 null sas dataset

对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;
Run Code Online (Sandbox Code Playgroud)

我理解的上面的代码应该只打印第一个注释,即空数据集.出于某种原因,虽然它也为第二个if条件返回true,并且也打印非空数据集.

请告诉我这里哪里出错了?

小智 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;
Run Code Online (Sandbox Code Playgroud)

if 0 then是一个用于强制执行数据步骤代码的虚拟条件; 如果使用了裸集语句,那么如果数据集"new"为空,则执行不会继续超过设置行.

更好的选择可能是使用宏来打开数据集并读取ANY属性:

%let dsid = %sysfunc (open(dataset_name));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid = %sysfunc (close(&dsid));
Run Code Online (Sandbox Code Playgroud)

&anyobs如果dataset_name包含至少一个观察(行)和至少一个变量(列),则宏变量将为1;如果它不包含任何观察但至少包含一个变量,则为0;如果它不包含任何观察值且没有变量,则为-1.