Statistical programming, matrix languages, and more

SAS IML - Macro variables in loops

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 9
Accepted Solution

SAS IML - Macro variables in loops

Due to macro pre-processing and run time execution, the following code always prints the sum for Var_C. I can use symget to get the value at run time, but it seems that I can only store this value in a regular variable, not a macro variable.
How can I assign the value for macro variable s so that it correctly updates at each loop iteration therefore printing the sum for Var_A, Var_B and Var_C?

proc iml;
    var_A = {1 2 3 4};
    var_B = {10 20 30};
    var_C = {100 200 300};

    varList = {"A", "B", "C"};
    do i = 1 to 3;
        call symputx("s", (varList[i]) );
        iteration = symget("s");

        print iteration;
        print (sum(var_&s.));
    end;

quit;

 


Accepted Solutions
Solution
2 weeks ago
Frequent Contributor
Posts: 136

Re: SAS IML - Macro variables in loops

I don't think you need to use the macro language at alll, as this can be done using indirect referencing with the VALUE function:

 

proc iml;
    var_A = {1 2 3 4};
    var_B = {10 20 30};
    var_C = {100 200 300};

    varList = {"A", "B", "C"};
    do i = 1 to 3;
        print (sum(value('var_' + varList[i])));
    end;
quit;

View solution in original post


All Replies
Trusted Advisor
Posts: 1,607

Re: SAS IML - Macro variables in loops

[ Edited ]

BogdanC wrote:

Due to macro pre-processing and run time execution, the following code always prints the sum for Var_C. I can use symget to get the value at run time, but it seems that I can only store this value in a regular variable, not a macro variable.
How can I assign the value for macro variable s so that it correctly updates at each loop iteration therefore printing the sum for Var_A, Var_B and Var_C?

proc iml;
    var_A = {1 2 3 4};
    var_B = {10 20 30};
    var_C = {100 200 300};

    varList = {"A", "B", "C"};
    do i = 1 to 3;
        call symputx("s", (varList[i]) );
        iteration = symget("s");

        print iteration;
        print (sum(var_&s.));
    end;

quit;

 


I'm struggling to see why a macro variable is needed here at all. In fact, I will state definitively that a macro variable is not needed here. Why make your life so complicated?

 

do i = 1 to 3;
        iteration = varList[i];
        print (sum(iteration));
end;

 

Solution
2 weeks ago
Frequent Contributor
Posts: 136

Re: SAS IML - Macro variables in loops

I don't think you need to use the macro language at alll, as this can be done using indirect referencing with the VALUE function:

 

proc iml;
    var_A = {1 2 3 4};
    var_B = {10 20 30};
    var_C = {100 200 300};

    varList = {"A", "B", "C"};
    do i = 1 to 3;
        print (sum(value('var_' + varList[i])));
    end;
quit;
Super User
Super User
Posts: 7,392

Re: SAS IML - Macro variables in loops

Macro is a text replacement function, nothing more.  You cannot use it in SAS code like that.  All it does is expand the code you have out based on some primitive logic.  My quesiton back to you would be why your doing ti this way in the first place, or it could just be your example.  Data should be put into datasets.  Then you can operate on that data in a variety of ways.  For example, taking wht you have posted:

data want;
  infile datalines missover;
  input v1 v2 v3 v4;
  r=sum(of v:);
  put _all_;
datalines;
1 2 3 4
10 20 30
100 200 300
;
run;
SAS Super FREQ
Posts: 3,475

Re: SAS IML - Macro variables in loops

Trying to combine PROC IML, which is an interactive language whose statements are parsed and executed sequentially, with the macro language, which is a preprocessor language, can lead to confusing situations. I highly recommend that you study the articles

"Macros and loops in the SAS/IML language"

and 

"Calling a global statement inside a loop"

 

I usually advise that folks not try to combine IML and macro statement in loops. I like to use macro statements to initialize arguments (names of data sets, names of variables, number of iterations, etc), and then run the IML program using IML control structures such as loops.  If necessary, at the end of the program I will write a data set or create some macro variables that summarize the results.

 

For your example, you don't need any macro variables. You can use the VALUE function to retrieve the value in a matrix whose name you specify. Thus v=VALUE("var_A") is equivalent to v=var_A. This is called "indirect assignment" and "indirect retrieval." See the article "Indirect assignment: How to create and use matrices named x1, x2,..., xn"

 

Thus the following program addresses your question:


proc iml;
    var_A = {1 2 3 4};
    var_B = {10 20 30};
    var_C = {100 200 300};

    varList = {"A", "B", "C"};
    do i = 1 to 3;
       VarName = "var_" + strip(varList[i]); 
       v = value(varName);
       print i (sum(v));
    end;
Super User
Posts: 6,928

Re: SAS IML - Macro variables in loops

This:

print (sum(var_&s.));

is evaluated by the macro processor while the do loop is compiled. Once the do loop runs, it never changes.

You should see the correct value in iteration, but never get the intended sum.

Can't you solve such a problem with a two-dimensional matrix?

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 9,662

Re: SAS IML - Macro variables in loops

VALUE() is for this kind of scenario.

 

proc iml;
    var_A = {1 2 3 4};
    var_B = {10 20 30};
    var_C = {100 200 300};

    varList = {"A", "B", "C"};
    do i = 1 to 3;
       iteration= value('var_'+varList[i]);

        print iteration;
        print (sum(iteration));
    end;

quit;
☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 317 views
  • 9 likes
  • 7 in conversation