Search code examples
sasglobal-variables

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. 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. How can I use VAR1 and VAR2?

Thank you!


Solution

  • I am not sure why you are making VAR1 and VAR2 as global rather than local. 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.

    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.

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

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