我正在搜索SAS 9.3宏语言中的 for 循环(如Python或R中)。 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和stackoverflow的新手,所以我希望我的问题不是太愚蠢。在Python和R中执行此操作非常简单,因此必须有一种简单的方法在SAS中执行此操作。
感谢您的帮助 - J. Muller
答案 0 :(得分:6)
我在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,我可以对此进行测试。)
答案 1 :(得分:4)
你当然可以这样解决问题:
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;
除了数据驱动之外,其效果与%do循环一样有效,这意味着如果您想更改调用,只需更改数据集(或者如果数据更改,则调用会自动更改!)。通常,SAS在设计为数据驱动编程时更有效,而不是完全编写代码。