我想在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?
谢谢!
答案 0 :(得分:0)
宏没有本地数组构造。术语“宏数组”是一个隐喻,表示范围可以访问具有相同基本名称和顺序(或索引)后缀的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;
答案 1 :(得分:0)
我不确定为什么要将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等,则只需从I和J进行构建。
%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);
您的WHERE语句也看起来不对。也许您的意思更像是:
%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;