3

在 Stata 中,您可以使用foreach 命令遍历字符值列表。到目前为止,我一直在尝试在 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;

我做错了什么或错过了什么?

提前致谢,

马蒂亚斯

4

3 回答 3

6

尝试这个:

%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);
于 2013-09-03T15:56:55.560 回答
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);

在这里,我只处理一次输入数据(如果需要,为了提高效率)在一个数据步骤中创建所有输出表。另外我正在创建一个“其他”表。要只处理列表中包含代码的记录,您可以在 SET 语句下添加 WHERE 语句并省略 else 输出其他;

于 2013-09-03T16:25:45.580 回答
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);

此版本使用COUNTWSCAN功能与修饰符仅使用空格 ( %str( )) 作为单词分隔符。

还使用新的宏getName根据 SAS 命名规则为数据集命名(注意%let name = ;只需在内部提供变量%loopit%getName进行填充)。

%getName将不允许的字符转换为下划线(如果您使用不同的分隔符具有相同的值,则此处可能存在名称冲突)。

于 2013-09-10T15:27:36.243 回答