在Stata中,您可以使用foreach command循环遍历字符值列表。我一直试图在SAS中做同样的事情到目前为止无济于事。我正在尝试在字符列的所有值上运行一系列数据和proc语句。我尝试了以下内容:
%let mylist = a b c; * These are all the values of a column called "code";
data mydata_@mylist; * Each element creates a new table;
set mydata;
where code=&mylist;
run;
我做错了什么或错过了什么?
提前致谢,
塞马蒂亚斯
答案 0 :(得分:4)
试试这个:
%macro loopit(mylist);
%let n = %sysfunc(countw(&mylist));
%do I=1 %to &n;
%let val = %scan(&mylist,&I);
data mydata_&val;
set mydata;
where code = "&val";
run;
%end;
%mend;
%let list=a b c;
%loopit(&list);
答案 1 :(得分:2)
基于DomPazz提供的修改版本:
data mydata;
length code $8;
input code;
cards;
a
a
b
c
n
;
run;
%macro loopit(mylist);
%let else=;
%let n = %sysfunc(countw(&mylist));
data
%do I=1 %to &n;
%let val = %scan(&mylist,&I);
mydata_&val
%end;
other
;
set mydata;
%do j=1 %to &n;
%let val = %scan(&mylist,&j);
%if &j ne 1 %then %do;
%let else=else;
%end;
&else if code = "&val" then output mydata_&val;
%if &j = &n %then %do;
else output other;
%end;
%end;
run;
%mend;
options mprint;
%let list=a b c;
%loopit(&list);
这里我只处理输入数据一次(如果需要,为了提高效率)在一个数据步骤中创建所有输出表。 我也正在创建一个“其他”表。要处理只包含list中代码的记录,可以在SET语句下添加WHERE语句,省略else输出other;
答案 2 :(得分:0)
%macro getName;
%let name = %sysfunc(translate(&val, __, -/));
%mend;
%macro loopit(mylist);
%let else=;
%let name=;
%let n = %sysfunc(countw(&mylist, %str( )));
data
%do I=1 %to &n;
%let val = %scan(&mylist,&I, %str( ));
%getName
mydata_&name
%end;
other
;
set mydata;
%do j=1 %to &n;
%let val = %scan(&mylist,&j, %str( ));
%getName
%if &j ne 1 %then %do;
%let else=else;
%end;
&else if code = "&val" then output mydata_&name;
%if &j = &n %then %do;
else output other;
%end;
%end;
run;
%mend;
options mprint;
%let list=a-a b/b c-;
%loopit(&list);
此版本使用带有修饰符的COUNTW
和SCAN
函数仅将空格(%str( )
)用作单词分隔符。
还使用新的宏getName
根据SAS命名规则为数据集撰写名称(注意%let name = ;
只需在%loopit
内提供变量以填充%getName
。
%getName
会将不允许的字符转换为下划线(如果您使用不同的分隔符,则可能存在潜在的名称冲突)。