如果 _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 中设置的数据集为空(零观测值)的主要内容,如果未能解决你的问题,请参考以下文章