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

Posted

技术标签:

【中文标题】如果 _N_ = 1 条件返回 true,即使在 SAS 中设置的数据集为空(零观测值)【英文标题】:if _N_ = 1 condition returns true even if the set dataset is empty (zero observations) in SAS 【发布时间】:2011-12-05 10:18:03 【问题描述】:

对 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】:

好的,这就是我的想法。第一个问题是您的宏调用在双引号中,因此在 SAS 甚至开始处理数据步骤之前由预处理器处理(无论 if 条件是否为真都执行)。您需要将要执行的参数放在单引号中而不是双引号中,以防止它被宏预处理器过早执行。

但是,此代码仍然无法在空数据集上运行,就好像在 set 行上提供的数据集是空的一样,然后整个数据步骤将终止,然后再执行任何其他代码。

第三,_N_ 被初始化为 1,而不是 0,并从那里在数据步边界上递增,因此 _N_ = 0 条件将始终为 false。

解决此问题的另一种方法是使用 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 是一个虚拟条件,用于强制执行数据步代码;如果使用了裸 set 语句,那么如果数据集“new”为空,则执行将不会继续超过 set 行。

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

%let dsid = %sysfunc (open(dataset_name));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid = %sysfunc (close(&dsid));

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

【讨论】:

谢谢加里!你的回答真的很有帮助。

以上是关于如果 _N_ = 1 条件返回 true,即使在 SAS 中设置的数据集为空(零观测值)的主要内容,如果未能解决你的问题,请参考以下文章

True or False

pdo 在多个查询上返回 true,即使其中一个失败

haskell - 指定 # 个条件为真

当条件为真时,Pandas将数据帧分成多个

如何在特定条件下返回不同的行?

左神算法书籍《程序员代码面试指南》——2_06判断一个链表是否为回文结构