即使 SAS 中设置的数据集为空(零观测值),if _N_ = 1 条件也会返回 true
对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 并打印非空数据集。
请让我知道我哪里出了问题?
A doubt on 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;
The above bit of code in my understanding should only print the first comment, i.e. empty dataset. For some reason though it is returning a true for the second if condition as well and printing non-empty dataset as well.
Please let me know where am I going wrong with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,这就是我认为正在发生的事情。第一个问题是宏调用用双引号引起来,因此在 SAS 甚至开始处理数据步骤之前就由预处理器进行处理(无论 if 条件是否为真都执行)。您需要将要执行的参数放在单引号而不是双引号中,以防止宏预处理器过早执行它。
但是,此代码仍然无法在空数据集上运行,就像设置行上提供的数据集为空一样,整个数据步骤将在执行任何进一步的代码之前终止。
第三,_N_ 初始化为 1,而不是 0,并在数据步边界上从那里递增,因此
_N_ = 0
条件将始终为 false。另一种解决方法是使用 nobs= 选项进行如下设置:
if 0 then
是一个虚拟条件,用于强制执行数据步骤代码;如果使用裸集语句,则如果数据集“new”为空,则执行将不会继续经过设置行。更好的选择可能是使用宏打开数据集并读取 ANY 属性:
如果 dataset_name 包含至少一个观察值(行)和至少一个变量(列),如果它不包含观测值但至少有一个变量,则为 0;如果它不包含观测值且不包含变量,则为 -1。
Okay, here's what I think is going on. The first problem is that your macro invocations are in double quotes, and therefore being processed by the pre-processor before SAS has even started to process the data step (executing regardless of whether the if condition is true or not). You need to put the argument to execute in single quotes rather than double quotes to keep it from being prematurely executed by the macro pre-processor.
This code still won't work on an empty dataset, however, as if the dataset supplied on the set line is empty then the entire data step terminates, before any further code is executed.
Thirdly, _N_ is initialised to 1, not 0, and incremented from there on the data step boundary, so the
_N_ = 0
condition will always be false.An alternative way of going about this would be to use the nobs= option to set as follows:
The
if 0 then
is a dummy condition used to force execution of the data step code; if a bare set statement were used then execution would not continue past the set line if the dataset "new" were empty.A better option might be to use macros to open the dataset and read the ANY attribute:
The macro variable
&anyobs
will be 1 if dataset_name contains at least one observation (row) and at least one variable (column), 0 if it contains no observations but at least one variable, and -1 if it contains no observations and no variables.