我正在搜索与for in 循环(类似于Python或R)的SAS9.3宏语言。DO loop似乎是解决方案,但并没有完全按照我的要求工作。我创建了一种方法,在数据步骤中使用do循环,但它不适用于宏语言。例如,在数据步骤中,此代码正在工作:
DATA _NULL_;
DO i = 1,3,5,9;
PUT i;
END;
RUN;然后,日志提示符如预期的那样:
1
3
5
9当我试图对宏中的%DO循环执行同样的操作时,就会出现错误。
%MACRO test();
%DO i = 1,2,4,9 ;
%PUT i = &i;
%END;
%MEND;
%test();日志将显示以下消息:
ERROR: Expected %TO not found in %DO statement.
ERROR: A dummy macro will be compiled我在SAS和堆栈溢出方面很新,所以我希望我的问题不要太愚蠢。在Python和R中这样做是如此简单,那么它必须有一种简单的方法在SAS中完成。
谢谢你的帮助- J.穆勒
发布于 2013-03-22 14:47:56
在SAS宏语言中,最接近这种模式的是:
%MACRO test();
%let j=1;
%let vals=1 2 4 9;
%do %while(%scan(&vals,&j) ne );
%let i=%scan(&vals, &j);
%put &i;
%let j=%eval(&j+1);
%end;
%MEND;
%test();(警告:未经测试,因为我已经没有SAS安装,所以我可以在上面测试。)
发布于 2013-03-22 14:46:39
你当然可以这样绕开它:
options mindelimiter=,;
options minoperator;
%MACRO test();
%DO i = 1 %to 9 ;
%if &i in (1,2,4,9) %then %do;
%PUT i = &i;
%END;
%end;
%MEND;
%test();但是,我认为您通常可以通过多次执行宏来避免这种调用,而不是试图控制宏中的循环。例如,想象一个数据集和一个宏:
data have;
input x;
datalines;
1
2
4
9
;;;;
run;
%macro test(x);
%put &x;
%mend test;现在,您希望对列表中的每个值调用一次%test()。好的,很容易做。
proc sql;
select cats('%test(',x,')') into :testcall separated by ' ' from have;
quit;
&testcall;这与您在循环中的%操作一样好,但它是由数据驱动的,这意味着如果您想要更改调用,您只需更改数据集(或者如果您的数据更改,调用将自动更改!)。一般来说,SAS在设计为数据驱动的编程而不是完全编写代码时更有效。
https://stackoverflow.com/questions/15573077
复制相似问题