SAS:迭代地在数组上进行宏循环

时间:2017-02-27 19:11:52

标签: arrays macros sas

在我的数据中,我将数组定义为以rev_开头的所有变量:

data df;
set def;
    array vnames rev:;
run;

现在我想在这个数组上重复means函数。例如,让我们说vnames中的每个元素都是一个不同的类变量,我喜欢我的命令。

让我们说rev:实际上扩展为rev1 rev2 rev3 revolution

所以我想要sas这样做:

proc means data=df;
var rev1;
run;

proc means data=df;
var rev2;
run;

proc means data=df;
var rev3;
run;

proc means data=df;
var revolution;
run;

现在我最终调用的函数可能更复杂。我以为我应该设置一个宏,然后一起运行数组和宏,但我不知道如何做到这一点。

我确实没有任何样本数据,但我们的想法是在命名数组上运行相同的命令(或一系列命令,即宏)。

4 个答案:

答案 0 :(得分:1)

听起来你只想要WAYS中的PROC MEANS声明。但是您的示例代码与您想要的描述不符。如果你真的想找到所有数值变量的方法并分别为许多不同的类变量运行它,那么这就是你想要的代码。

proc means data=have ;
  class rev: ;
  ways 1;
run;

答案 1 :(得分:1)

汤姆的答案是正确的,如果它解决了你的实际问题;一般来说,SAS提供了很多方法来做一些不需要宏来进行暴力破解的方法。毫无疑问,一个PROC步骤会比多个步骤更快。

但是,如果您确实需要,答案是查看dictionary.columnssashelp.vcolumn甚至proc contents输出。特别是因为rev变量列表而不是只是一个数字迭代器(revolution),所以不能只是用数字迭代。您定义的array不会超过该数据步骤,不要忘记 - 它们是数据步骤编程工具,但在宏语言或过程中没有用处。当然,revs:仍在流程中可用,但vnames[1]不是。

说你的宏是:

%macro runmeans(data=, var=, out=);
  proc means data=&data.;
    var &var.;
    output out=&out. mean(&var.)=;
  run;
%mend runmeans;

然后你可以这样做:

proc sql;
  select cats('%runmeans(data=SASHELP.CLASS, var=',name,',out=M_',name,')')
     into :runmeanslist separated by ' '
     from dictionary.columns
     where libname='SASHELP' and memname='CLASS' and upcase(name) like '%EIGHT'; *weight height;
quit;

&runmeanslist.

如果您对SQL感到不舒服,可以使用call executesashelp.vcolumn数据集或写入文件的proc contents输出在数据步骤中执行相同操作。< / p>

答案 2 :(得分:0)

以下是使用ways中的proc means仅执行一次(而不是循环或多次执行)而不使用通配符的示例。

proc sql;
  select name into :varlist separated by ' '
    from dictionary.columns
    where libname='SASHELP' and memname='CLASS'
    and not (upcase(name) like '%EIGHT');
quit;

proc means data=sashelp.class;
  class &varlist.;
  ways 1;
run;

更像那样的东西。 (我在这里转换类声明,并使用高度/权重的VAR和类变量非数字,因为这更有意义)。

答案 3 :(得分:0)

正如其他答案所暗示的那样,在项目的大背景下,可能有更好的方法来获得所需。话虽如此,我认为call execute()值得一提,因为它接近你特别想要的东西。

%macro SomeProc(dataset,variable);
    proc univariate data=&dataset.;
        var &variable.;
    run;
%mend SomeProc;

data _null_;
    set sashelp.Cars end=lastObs;
    array vnames[*] MPG_:;
    if lastObs then do i=1 to dim(vnames);
        call execute('%SomeProc(sashelp.Cars,'||vname(vnames[i])||')');
    end;
run;