DATA Step, Macro, Functions and more

How to loop through values in a macro

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 7
Accepted Solution

How to loop through values in a macro

Hello,

I’m using flexMIRT software to run a simulation study but have to use SAS to automate the creation of the syntax files and then call flexMIRT. I’ve created a macro to create the flexMIRT syntax file but am just struggling a bit when invoking the macro to run through the simulation conditions.

Here is the macro:

%MACRO flex_sim (ss=, cl=, BV=, Ni=, seed=, rep=);

data _NULL_;

file "C:\Users\KMarino\&ss._&cl._&BV._&Ni._&rep..flexmirt";

PUT #1 @1 '<Project>'

      #2 @3 "Title= ""IRT multilevel simulation, &ss examinees &cl level two cluters, &Ni items, &BV between variance"";"

      #3 @3 'Description="practice";'

      #5 @1 '<Options>'

      #6 @1 'Mode=Simulation;'

      #7 @3 "Rndseed = &seed;"

      #8 @3 'ReadPRMFile ="C:\Users\kmarino\Generating Parameter File.txt";'

      #10 @1 '<Groups>'

      #11 @1 '%GI%'

      #12 @3 "File = ""C:\Users\KMarino\&ss._&cl._&BV._&Ni._&rep..dat"";"

     #13 @3 "Varnames = item1-item&Ni;"

      #14 @3 "N=&ss;"

      #15 @3 'Dimensions=2;'

      #16 @3 'Between=1;'

      #17 @3 "Nlevel2=&cl;"

      #19 @1 '<Constraints>'

      #20 @3 "Value Cov(1,1), &BV;"

      #21 @3 "Prior (item1-item&Ni), Guessing : Normal(-1.39, 0.5);"

;

run;

%MEND flex_sim;

When I invoke the macro (%flex_sim (ss=500, cl=10, BV=0.053, Ni=10, seed=92730, rep=1)Smiley Winkit works fine.

Now I want to loop through all these values with a unique seed value for each replication:

data flexMIRT.design;

DO ss=300, 1000, 5000;

      DO cl=10, 60, 100, 150;

           DO BV=0.053, 0.11, 0.25, 0.43, 1.00;

                DO Ni=10, 20, 50, 70;

                     Do rep=1 to 250;

                          output;

                     end;

                end;

           end;

      end;

end;

run;


This will result in 60,000 syntax files which I will then run through flexMIRT. I'm stuck on how to loop through these values. Any help would be greatly appreciated!!


Accepted Solutions
Solution
‎05-13-2015 10:18 AM
Super User
Posts: 9,681

Re: How to loop through values in a macro

Code not tested.


data _null_;

DO ss=300, 1000, 5000;

      DO cl=10, 60, 100, 150;

           DO BV=0.053, 0.11, 0.25, 0.43, 1.00;

                DO Ni=10, 20, 50, 70;

                     Do rep=1 to 250;

                          call execute (catt('%flex_sim (ss=', ss ,', cl=', cl ,', BV=',bv,', Ni=',ni,', seed=',seed,', rep=',rep,')')) ;

                     end;

                end;

           end;

      end;

end;

run;

View solution in original post


All Replies
Trusted Advisor
Posts: 1,615

Re: How to loop through values in a macro

Instead of your dataset flexMIRT.design, you want a macro containing macro %DO loops.

Parital Code

%macro do_this;

     %let ss_list=300 1000 5000;

     %do ii=1 %to %sysfunc(countw(&ss_list));

          %let ss=%scan(&ss_list,&ii,%str( ));

...

     %end;

%mend;

Instead of the output in your data step, this is where you would put

%flex_sim (ss=&ss, cl=&cl, BV=&bv, Ni=&ni, seed=92730, rep=&rep)

Solution
‎05-13-2015 10:18 AM
Super User
Posts: 9,681

Re: How to loop through values in a macro

Code not tested.


data _null_;

DO ss=300, 1000, 5000;

      DO cl=10, 60, 100, 150;

           DO BV=0.053, 0.11, 0.25, 0.43, 1.00;

                DO Ni=10, 20, 50, 70;

                     Do rep=1 to 250;

                          call execute (catt('%flex_sim (ss=', ss ,', cl=', cl ,', BV=',bv,', Ni=',ni,', seed=',seed,', rep=',rep,')')) ;

                     end;

                end;

           end;

      end;

end;

run;

Occasional Contributor
Posts: 7

Re: How to loop through values in a macro

This worked perfectly! Your code easily creates the 60,000 syntax files but now I need to add in a unique seed number for each value of the do loop. Any further suggestions?

Super User
Posts: 5,084

Re: How to loop through values in a macro

Given that you have already created flexMIRT.design, the easiest way would be to re-use it to generate 60,000 calls to your macro:

data _null_;

set flexMIRT.design;

call execute('flex_sim (ss=' || put(ss, 4.) || ', cl=' || put(cl, 3.) || ', BV=' || (put(BV, 5.3) || ', Ni=' || put(ni, 2.) || ', seed=' || put(_n_+92730, 6.)

    || ', rep=' || put(rep, 3.) || ')' );

run;

You will have to check the formats I used, to make sure they are valid for all the looping values that you intend to use.

This sort of code could have been used in the original DATA step that created flexMIRT.design (either to replace the OUTPUT statement, or in addition to the OUTPUT statement).

Good luck.

Looks like you have another CALL EXECUTE suggestion ... perhaps a combination of the two would be best.  CATT simplifies the code by performing numeric to character conversions without adding the PUT function.  On the other hand, you wanted some logic to use a different seed for each run and _N_+92730 will do that.

Occasional Contributor
Posts: 7

Re: How to loop through values in a macro

Thanks! As you suggested, I combined part of your code with the prior CALL EXECUTE suggestion to incorporate a different seed value for each run (below).  I must be doing something wrong because using the code below gives me 92731 for each run. Any thoughts on what might be wrong? Also, could you explain what the "6." in the PUT statement is referencing? 

data _null_;

DO ss=300, 1000, 5000;

      DO cl=10;

           DO BV=0.053, 1.00;

                DO it=10;

                     Do rep=1 to 10;

                          call execute (catt('%flex_sim (ss=', ss ,', cl=', cl ,', bv=',bv,', it=',it,', seed=' || put(_N_+92730, 6.)|| ', rep=',rep,')')) ;

                     end;

                end;

           end;

      end;

end;

run;

Super User
Posts: 5,084

Re: How to loop through values in a macro

Yes, when using nested DO loops _N_ doesn't increment.  It works with the SET statement, but not with the loops.

The fix is simple.  Add just before the CALL EXECUTE statement:

_N_ + 1;

In a PUT function, the second parameter (6. in this case) indicates how to express the value.  So this means to use a six-digit format to express the seed.

Occasional Contributor
Posts: 7

Re: How to loop through values in a macro

Perfect! I was able to create all the syntax files. I'm very grateful for the help!

☑ This topic is SOLVED.

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

Discussion stats
  • 7 replies
  • 403 views
  • 7 likes
  • 4 in conversation