我需要一种方法来动态返回当前数据步骤中的变量数。
使用SAS NOTE 24671: Dynamically determining the number of observations and variables in a SAS data set,我提出了以下宏。
%macro GetVarCount(dataset);
/* Open assigns ID to open data set. Assigns 0 if DNE */
%let exists = %sysfunc(open(&dataset));
%if &exists %then
%do;
%let returnValue = %sysfunc(attrn(&exists, nvars));
%let closed = %sysfunc(close(&exists));
%end;
/* Output error if no dataset */
%else %put %sysfunc(sysmsg());
&returnValue
%mend;
不幸的是,由于尚未创建数据集,因此在数据集的初始传递时会出错。在第一次传递之后,创建了一个具有0个观察值的数据集,宏可以访问该表和变量数。
例如,
data example;
input x y;
put "NOTE: [DEV] There are %GetVarCount(example) variables in the EXAMPLE data set.";
datalines;
1
2
;
run;
第一次运行产生:
ERROR: File WORK.EXAMPLE.DATA does not exist.
WARNING: Apparent symbolic reference RETURNVALUE not resolved.
NOTE: [DEV] There are &returnValue variables in the EXAMPLE data set.
第二次运行产生:
NOTE: [DEV] There are 2 variables in the EXAMPLE data set.
有没有办法在第一次运行数据步骤时获取数据集中的变量数量?
答案 0 :(得分:2)
在您的示例中,您尝试确定数据步骤中活动变量的数量 - 这不一定与输出数据集中的变量数量相同,因为( a)可能没有输出数据集,(b)某些变量可能会被丢弃。
记住这个警告,如果你真的想这样做,那么这就行了:
data fred;
length x y z $ 20 f g 8;
array vars_char _character_;
array vars_num _numeric_;
total_vars = dim(vars_char) + dim(vars_num);
put "Vars in data step: " total_vars;
run;
这可以通过使用特殊的_character_
和_numeric_
关键字来创建当前缓冲区中所有字符和数字变量的数组,以及dim()
函数来获取这些数组的大小
它只计算声明数组时存在的变量,因此在这种情况下它不会计算total_vars
。
你可以将它包装在一个宏中,如:
%macro var_count(var_count_name):
array vars_char _character_;
array vars_num _numeric_;
&var_count_name = dim(vars_char) + dim(vars_num);
%mend;
然后像:
一样使用它data fred;
length x y z $ 20 f g 8;
%var_count(total_vars);
put "Vars in data step: " total_vars;
run;
答案 1 :(得分:0)
尝试打开已创建的数据集。
'打开'函数需要将存在的数据集存在,我想你想要打开'为您提供已打开数据集的ID;事实并非如此。
它仅在第一次传递(而不仅仅是第二次传递)之后才起作用的原因是因为第一次传递创建了一个空数据集,其中包含有关其包含的变量的元数据。
首先使用库永久存储数据集,然后尝试使用宏从中读取数据:
Data <lib>.dataset;
更新
@Reeza已经在评论中给了你答案。
另一种选择:
使用put _all_;
会将所有变量打印到日志中,如果您将put放入文件然后读取并计算&#39; =&#39;迹象表明你也可以得到变数。只需从计数中删除_n_ and _ERROR_
即可。