简体   繁体   English

将数据步骤的全局MACRO变量引用到SAS中的proc过程

[英]Refering Global MACRO Variable of a data step to a proc procedure in SAS

I want to use variables in my list in proc procedures. 我想在proc过程的列表中使用变量。 Here is simplified version of my code. 这是我的代码的简化版本。

%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;

But VAR1 and VAR2 do not have in proc corr procedure. 但是VAR1和VAR2没有proc corr程序。 How can I use VAR1 and VAR2? 如何使用VAR1和VAR2?

Thank you! 谢谢!

Macros do not have a native array construct. 宏没有本地数组构造。 The term 'macro array' is a metaphor for the case of a scope having access to N macro variables with the same base name and sequential (or index) suffixes. 术语“宏数组”是一个隐喻,表示范围可以访问具有相同基本名称和顺序(或索引)后缀的N个宏变量。 You can outright assign each variable that acts as an array element, or you can have some spiffy code that splits out variables from a textual list. 您可以直接分配充当数组元素的每个变量,也可以使用一些巧妙的代码从文本列表中分离出变量。

'Indexed' variables are resolved in a loop using construct &&&. “索引”变量使用构造&&&循环解析。 For example: 例如:

%let A2 = 1234;
%let index = 2;

%let var1 = &&A&index;       %* var1 gets 1234;

Part of the SAS supervisors responsibilities is to implicitly resolve macro expressions, recursing on a token as required. SAS主管的部分职责是隐式解析宏表达式,并根据需要在令牌上递归。 Doubled &'s are halved at each implicit resolution iteration. 在每个隐式分辨率迭代中,将&的两倍减半。 Such as: 如:

&&A&index -> &A2 -> 1234

Your code can change to 您的代码可以更改为

%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;

I am not sure why you are making VAR1 and VAR2 as global rather than local. 我不确定为什么要将VAR1和VAR2设置为全局而不是本地。 They appear to only have meaning within this macro. 它们似乎仅在此宏中具有含义。 At the end of the macro they will just have the last value assigned to them inside the %do loops. 在宏的末尾,它们只会在%do循环中分配有最后一个值。

Also you do not seem to understand how the macro processor works. 另外,您似乎还不了解宏处理器的工作方式。 It will complete its work on converting macro triggers into text BEFORE the generated data step runs. 在生成的数据步骤运行之前,它将完成将宏触发器转换为文本的工作。 If you re-order your statements to reflect that it will be clearer why VAR1 and VAR2 do not get the values you want and why your data step is not doing anything at all. 如果您对语句进行重新排序以反映出以下事实,则将更清楚为什么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;

If you really want to use variable names CAT11,CAT21, etc. then just build them from I and J. 如果您确实要使用变量名称CAT11,CAT21等,则只需从I和J进行构建。

%let var1=cat1&i;
%let var2=cat2&j;

If you really have lists of variable names then put the lists in macro variables. 如果确实有变量名列表,则将这些列表放在宏变量中。

%let varlist1=cat11 cat12;
%let varlist2=cat21 cat22;
%let var1=%scan(&varlist1,&i);
%let var2=%scan(&varlsit2,&j);

Your WHERE statement looks wrong also. 您的WHERE语句也看起来不对。 Perhaps you meant something more like: 也许您的意思更像是:

%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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM