我有一个宏,在给定的数据集中查找变量名称 . 如果缺少宏正在查找的变量名称,则缺少的变量名称将添加到表中:
%macro miss(ds, var);
%local rc dsid result;
%let dsid=%sysfunc(open(&ds));
%if %sysfunc(varnum(&dsid,&var)) > 0 %then %do;
%put &var present;
%end;
%else %do;
insert into work.compare(missing) values("&var")
%end;
%mend;
proc datasets library=work nolist nodetails;
delete compare;
run;
proc sql;
create table work.compare (missing char(15));
%miss(ctr.panup_in, u_name);
quit;
proc print noobs data=work.compare;
run;
需要为55个不同的变量名运行此检查 . 目前,我只把每一个列为一个
%miss(ctr.panup_in, varname);
线 .
出于实际原因,我想将变量列表指定为列表,例如%let dictionary = var1 var2 var3等 . 我现在的斗争是找到宏循环变量列表的方法 . 到目前为止我尝试过的所有内容都会导致“Stament is not valid”错误
insert into work.compare(missing) values("&var")
命令 .
有没有人对如何做到这一点有任何建议?
4 回答
这循环了一组变量,其中变量用“|”分隔 . 也可以在扫描功能中使用和指定任何其他分隔符 .
你真的需要检查吗?您可以定义要删除的所有变量的零obs数据集,如果它们丢失则使用未执行的SET来包含它们 .
您可以使用修改来删除不需要的变量,以使用所有变量更新到主服务器 .
另一个选择是将变量存储在表中 - 它们可能已经存在于一个表中 . 也许是dictionary.columns?
事实上,你可以通过dictionary.columns简单地完成整个过程 . 例如:
如果您不必创建数据集(如果它已经存在),则这当然更容易 - 或者作为另一个数据集中存在的变量列表,或者直接通过数据或类似创建数据集 . 可能的情况是,您有一些具有此信息的数据,不仅仅是硬编码的%let语句 .
一个示例,用于标识
CLASSFIT
中的变量,而不是CLASS
中的变量(均在SASHELP
库中):如果您确实需要一个名称不在数据集中的表,那么您可以使用数据步骤并消除使用宏或PROC SQL的复杂性 .
现在,宏解决方案可能有用的地方是,如果您想传入列表并获取另一个列表,而不生成任何代码 .
这样你就可以在语句中间调用宏,就像函数调用一样 .