BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
BogdanC
Fluorite | Level 6

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;

 

1 ACCEPTED SOLUTION

Accepted Solutions
IanWakeling
Barite | Level 11

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

6 REPLIES 6
PaigeMiller
Diamond | Level 26

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

 

--
Paige Miller
IanWakeling
Barite | Level 11

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;
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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;
Rick_SAS
SAS Super FREQ

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;
Kurt_Bremser
Super User

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?

Ksharp
Super User

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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 6 replies
  • 2630 views
  • 9 likes
  • 7 in conversation