我想在proc过程中使用列表中的变量。这是我的代码的简化版本。
%MACRO CORRMAKER(file,data);
%DO I=1 %TO 2;
%DO J=1 %TO 2;
data _NULL_;
ARRAY VAR1LIST[2] $ A1-A2 ('CAT11' 'CAT12');
ARRAY VAR2LIST[2] $ B1-B2 ('CAT21' 'CAT22');
%GLOBAL VAR1 VAR2;
%LET VAR1=VAR1LIST[&I];
%LET VAR2=VAR2LIST[&J];
run;
proc corr data=&file out=&data&I&J RANK noprob;
var INNERVAR1 INNERVAR2 INNERVAR3 INNERVAR4;
where COND1=&VAR1 COND2=&VAR2;
run;
%END;
%END;
%MEND;
,但是var1和var2在Proc Corr过程中没有。如何使用var1和var2?
谢谢!
我不确定为什么您将var1和var2作为全局而不是局部。它们似乎仅在此宏中具有意义。在宏的末尾,他们将在%do
循环中分配给它们的最后一个值。
您也似乎不了解宏处理器的工作原理。它将完成在生成数据步骤运行之前将宏触发器转换为文本的工作。如果您重新排序您的语句,以反映出Var1和Var2无法获得所需的值以及为什么您的数据步骤根本没有做任何事情的情况更清楚。
%LET VAR1=VAR1LIST[&I];
%LET VAR2=VAR2LIST[&J];
data _NULL_;
ARRAY VAR1LIST[2] $ A1-A2 ('CAT11' 'CAT12');
ARRAY VAR2LIST[2] $ B1-B2 ('CAT21' 'CAT22');
run;
如果您真的想使用变量名称CAT11,CAT21等。
%let var1=cat1&i;
%let var2=cat2&j;
如果您确实有变量名的列表,则将列表放入宏变量中。
%let varlist1=cat11 cat12;
%let varlist2=cat21 cat22;
%let var1=%scan(&varlist1,&i);
%let var2=%scan(&varlsit2,&j);
您的陈述看起来也错了。也许您的意思更像是:
%let values1 = cat11 cat12 ;
%let values2 = cat21 cat22 ;
%do i=1 %to 2 ;
%do j=1 %to 2 ;
....
where cond1="%scan(&values1,&i)" and cond2="%scan(&values2,&j)";
....
%end;
%end;
宏没有本机数组构造。术语"宏数组"是一个隐喻的示波器的一个隐喻,该示波器具有具有相同基本名称和顺序(或索引)后缀的n个宏变量。您可以直接分配充当数组元素的每个变量,也可以使用一些散布的代码,从文本列表中分解变量。
'索引'变量通过构造&&&。在循环中解析。例如:
%let A2 = 1234;
%let index = 2;
%let var1 = &&A&index; %* var1 gets 1234;
SAS主管的一部分责任是隐式解析宏表达式,根据需要在令牌上递归。在每个隐式分辨率迭代中,两倍的及时都将其减半。例如:
&&A&index -> &A2 -> 1234
您的代码可以更改为
%MACRO CORRMAKER(file,data);
%local A1 A2 B1 B2 I J VAR1 VAR2;
%let A1 = CAT11;
%let A2 = CAT12;
%let B1 = CAT21;
%let B2 = CAT22;
%DO I=1 %TO 2;
%DO J=1 %TO 2;
%LET VAR1=&&A&I;
%LET VAR2=&&B&J;
proc corr data=&file out=&data&I&J RANK noprob;
var INNERVAR1 INNERVAR2 INNERVAR3 INNERVAR4;
where COND1="&VAR1" and COND2="&VAR2";
run;
%END;
%END;
%MEND;