我有一个医疗数据集,患者来自几家医院。我想要得到的是一个Excel文件,每张纸都专门用于特定的医院。我有一个变量说明每个患者来自哪一个所以我所要做的就是为这个变量的每个值进行子集化和导出。
我写这个宏是为了一个特定的值:
%macro exp_subset(table,var,value,out);
DATA &table._&var._&value;
SET &table;
where &var = &value;
run;
proc export
data=&table._&var._&value
dbms=EXCEL
LABEL
OUTFILE="<path>\&out..xls"
REPLACE;
SHEET="&var._&value";
run;
%mend;
它工作正常。
但是,我在变量的所有值上都无法应用它。在搜索了如何操作后,我尝试了call execute()
:
%macro exp_subsets_all(table,var,out);
proc sql noprint;
create table dist_var as /*this comes from another post of SO :P */
select distinct &var
from &table
;
quit;
data _null_;
set dist_var
(rename=(&var=values));
call execute ("%exp_subset(&table,&var,"||trim(left(values))||",&out)");
run;
%mend;
但它不起作用,我不太了解错误。
同样,单独使用%exp_subset()
时没有这样的错误......
我对call execute()
非常新,而且我不确定我能做什么或不能做什么。在我看来,我应该能够以这种方式使用它,但我错了吗?
如果你想测试一下这个表(你之前必须在第一个宏中指定一个路径):
DATA test;
input x y z;
cards;
1 2 3
4 2 6
7 8 9
7 11 8
;
run;
%exp_subset(test,x,7,table1);
%exp_subsets_all(test,y,table2);
答案 0 :(得分:3)
我对此有一些建议。
首先,每当构建一个宏调用时,使用单引号。这避免了早期解决问题。
call execute('%exp_subset('...)
您可以在第一位之后使用双引号,但包含%
的部分应包含单引号。如果您愿意,也可以添加%NRSTR
,但单引号更简单。
其次,%exp_subsets_all
宏可以更简单。
%macro exp_subsets_all(table,var,out);
proc sql noprint;
select distinct cats('%exp_subset(',"&table,&var,",&var.,",&out)")
into :calllist separated by ' '
from &table
;
quit;
&calllist.
%mend;
它的性能可能没有什么不同,但它再次更简单。唯一需要注意的是,如果从调用执行调用此宏,则需要小心 - 如果是这样,它必须包含在%nrstr
中。
第三,第一个宏应该是一步:
%macro exp_subset(table,var,value,out);
proc export
data=&table.
dbms=EXCEL
LABEL
OUTFILE="<path>\&out..xls"
REPLACE;
SHEET="&var._&value";
where &var = &value;
run;
%mend;
答案 1 :(得分:2)
我确信有更简单的方法可以实现您想要实现的目标,但是您的代码失败了,因为您在data _NULL_;
datastep中出现了一些语法错误:
<强> OLD 强>
data _null_;
set dist_var;
rename=(&var="values");
call execute ("%exp_subset(&table,&var,"||values||",&out)");
run;
新强>
data _null_;
set dist_var
(rename=(&var=values));
mac=%NRSTR("%exp_subset(&table,&var,"||trim(left(values))||",&out)");
call execute(mac);
run;
编辑:添加了NRSTR以防止%exp_subset提前解析。
<强>更改强>
重命名已更改为数据集选项,之前它尝试使用值(y =“values”)分配一个名为“rename”的新变量,该值是布尔表达式,计算结果为零。您可以通过将_NULL_
替换为数据集名称并查看生成的数据集来查看此内容。
在日志中注意到在使用exp_subset
函数执行call execute
时存在与数据集名称形成相关的语法错误,因此将trim(left(values))
添加到调用执行中,它会删除values
值周围的空格,并允许正确形成数据集名称。
我最终得到了名为:
的数据集我还使用OPTIONS MPRINT;
这是一个有用的语句来运行调试宏,因为它会显示在日志中执行的代码:
MPRINT(EXP_SUBSETS_ALL): DATA test_y_8;
MPRINT(EXP_SUBSETS_ALL): SET test;
MPRINT(EXP_SUBSETS_ALL): where y = 8;
MPRINT(EXP_SUBSETS_ALL): run;
MPRINT(EXP_SUBSETS_ALL): DATA test_y_11;
MPRINT(EXP_SUBSETS_ALL): SET test;
MPRINT(EXP_SUBSETS_ALL): where y = 11;
MPRINT(EXP_SUBSETS_ALL): run;
如果在可能会生成大量语句的宏上使用,请记得将其关闭,因为您将填充日志:
OPTIONS NOMPRINT;