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

Hi,

I was wondering if anyone could help me out with the following question. I've written a program in Base 9 with multiple data steps (and proc prints / reports). The outcome is based on the input variables, as stated at the beginning of the program (the &LET statements). Maybe useful to mention: in the datasteps itself, there are several other macro's created by the CALL SYMPUT statement (but these macro's are part of the calculations in the datastep, nothing else).

Now I want to run like 10.000 simulations (so different %LET statements). Is there a way to do this? Creating another dataset with the variables of each %LET statement and make the whole thing just 1 macro with another CALL SUMPUT? Or is this not possible? Thanks for your answer in advance!

The code looks like this:

/* Input variables new system*/

%Let example1='1';

%Let example2='5';

%Let example3='20';

%Let example4='35';

%Let example5='0';

%Let example6='3';

%Let example7='5';

Datastep 1

Proc Print 1

Data step 2

Proc Print 2

Etc.

1 ACCEPTED SOLUTION

Accepted Solutions
11 REPLIES 11
MikeZdeb
Rhodochrosite | Level 12

hi ... here are some ideas (I'm sure you'll get lots of suggestions) ...

you could put those 10,000 values in a data set then uses something like ...

* fake data ... put 5 values in a data set;

data x;

do _n_=1 to 5;

   value = ceil(100*ranuni(999));

   output;

end;

run;

* create a macro that reads the data set one observation per iteration of a loop;

* create a new macro variable at each iteration ... your code goes between %end and %mend;

%macro iterations;

%do j=1 %to 5;

data _null_;

   nrec = &j;

   set x point=nrec;

   call symputx("example&j",value);

   stop;

run;

* look at the LOG;

%put at iteration %j macro variable example&j value is &&example&j;

%end;

%mend;

%iterations;


or ... do you really need a new macro variable each time or just the same macro variable with a new value at each iteration ...


* give the same macro variable a new value at each iteration;

* your code goes between %end and %mend;

%macro iterations;

%do j=1 %to 5;

data _null_;

   nrec = &j;

   set x point=nrec;

   call symputx("example",value);

   stop;

run;

* look at the LOG;

%put at iteration %j macro variable example value is &example;

%end;

%mend;

or if you just need a random number at each iteration of the loop ...

* new value for macro variable generated at each iteration of the loop;

* your code goes inside the macro loop;

%macro iterations;


%do j=1 %to 5;

%let example = %sysfunc(ceil(100*%sysfunc(ranuni(999))));

%put at iteration %j macro variable example value is &example;

%end;


%mend;

Wouter
Obsidian | Level 7

Thanks for your answer! And I assume I can use multiple call symput statements below each other?



%do j=1 %to 5;

data _null_;

   nrec = &j;

   set x point=nrec;

   call symputx("example&j",value);

   stop;

run;

Wouter
Obsidian | Level 7

Hi, maybe you can help me one more time with this problem. I've got a dataset with round about 8 different variables (50k on rows or someting) and I want to run a simulation using this file. How can I create a simulation with different 'Symputs' at one time? Changing the code in something like beneath doesn't work...

%macro iterations;

data _null_;

   SET SIMULATION_SAMPLE_SET;

   nrec = &j;

   nrec = &x;

   nrec = &y;

   set x point=nrec;

   call symputx("example&j",value);

   call symputx("example&x",value);

   call symputx("example&y",value);

   etc.

   stop;

run;

* look at the LOG;

%put at iteration %j macro variable example&j value is &&example&j;

%put at iteration %x macro variable example&j value is &&example&x;

%put at iteration %y macro variable example&j value is &&example&y;

%end;

%mend;

%iterations;

MikeZdeb
Rhodochrosite | Level 12

hi ... still not exactly sure what you are doing, but this gives new values to three macro variables at each iteration

the values are based on data provided from your data set ...

also, I would read the reference cited by Rick Wilkin ... Simulation in SAS

and also worth reading is  ... Don't Be Loopy: Re-Sampling and Simulation the SAS® Way ... http://www2.sas.com/proceedings/forum2007/183-2007.pdf

data SIMULATION_SAMPLE_SET;

input x y z;

datalines;

1 2 3

4 5 6

7 8 9

;

%macro iterations;

%do j=1 %to 3;

data _null_;

   nrec = &j;

   set SIMULATION_SAMPLE_SET point=nrec;

   call symputx("xx",x);

   call symputx("xy",y);

   call symputx("xz",z);

   stop;

run;

* look at the LOG;

%put at iteration &j macro variable xx value is &xx;

%put at iteration &j macro variable yy value is &yy;

%put at iteration &j macro variable zz value is &zz;

%end;

%mend;

%iterations;


you could also try PROC SQL to generate the macro variables (the separated by clauses trim the values of the macro variable, if you have V9.3 you can substitute the option TRIMMED for the clause SEPARATED BY ' ') ...


%macro iterations;

%do j=1 %to 3;


proc sql noprint;

select x, y, z into

:xx separated by '',

:yy separated by '',

:zz separated by ''

from SIMULATION_SAMPLE_SET (firstobs=&j obs=&j);

quit;

* look at the LOG;

%put at iteration &j macro variable xx value is &xx;

%put at iteration &j macro variable yy value is &yy;

%put at iteration &j macro variable zz value is &zz;

%end;

%mend;

Wouter
Obsidian | Level 7


Hi,

Thanks again! But what I'm trying to do is to fill the %LET statements at the top of my code with a huge amount of figures from a dataset. From there, I need the outcome from the input from the dataset, and the output of the datasets I've already made. In words: I've created several datasets which contains macro's, and I want to test this program. For this, I want to use a dataset with multiple variables. The outcome should be the variables from the external file, and the output of my own written file.

I tried to use and adapt the code below, but I can't get the output from my own file combined with these data. Do you have any idea? My file contains several other named macro's inside also which can be used as output in each loop, I thought, by using a %put in my own files. But this don't work...

%macro iterations;

%do j=1 %to 3;

data _null_;

   nrec = &j;

   set SIMULATION_SAMPLE_SET point=nrec;

   call symputx("xx",x);

   call symputx("xy",y);

   call symputx("xz",z);

   stop;

run;

* look at the LOG;

%put at iteration &j macro variable xx value is &xx;

%put at iteration &j macro variable yy value is &yy;

%put at iteration &j macro variable zz value is &zz;

%end;

Data test;

if A=B then C=4;

Else...

etc...

call symput('testtest',C);

run;

%mend;

%iterations

Rick_SAS
SAS Super FREQ

If you care about efficiency, you might want to look at the article Simulation in SAS

Astounding
PROC Star

Wouter,

As difficult as it may be for you to believe, your requirements are still only partially clear.  I suspect that CALL EXECUTE would be a valuable tool here.  Here's a simplified version, based on the your first three values:

%let example1='1';

%let example2='5';

%let example3='20';

For illustration purposes, suppose this needs to generate:

proc print data=dataset1;

run;

proc print data=dataset5;

run;

proc print data=dataset20;

run;

Here is how CALL EXECUTE would approach the task, by putting the three values into a DATA step instead of macro variables:

data _null_;

input example $;

call execute ('proc print data=dataset' || strip(example) || '; run;');

datalines;

1

5

20

;

I realize the code you are trying to generate will be a whole lot more complex than a PROC PRINT, and that the values within the DATA step will do more than identify which data set to process.  Still, the approach is likely to be helpful.  If you post more of what you are trying to do, we can work out how to make it happen.

Good luck.

Wouter
Obsidian | Level 7

Hi,

I think this is not what I mean. I've written a code, which calculates several values, based on its input. The input is given, right now, by the %LET statements above the code:

%LET X=1

%LET Y=2

%LET B=3

The code contains just some datasteps, which uses the variables as created by the %LET statements.

For example:

Data test1;

A = &X*20;

run;

Proc print data=test1;

run;

The code also contains some macro's which are created inside the code, like:

Data test2;

B = Y*30;

Call symput ('tester',F)

run;

This macro is used again in other datasteps within the same program.

If I run this program, I get a list (all the proc print statements below each other), based on the values which are given by the %LET statements above the program. To test the program, I want to use an external SAS file which contain values for those %LET statements. But how can I run the program and get the output of all the values as presented in the external SAS file?

So the solution should be near, I get a logfile with all the different %LET statements from the external datafile, but I need also the variables that are created by my own program add to this.

So, when I get the output:

X=1

Y=2

B=3

I also need the output (calculations) added from my own datasets.

Astounding
PROC Star

We might be closer than you think.  Consider ...

When you get to the point of issuing this statement, there are alternatives:

call symput('tester', F);

Instead of using CALL SYMPUT, you could use CALL EXECUTE.  The value of F, as well as all existing macro variables, would be available to help CALL EXECUTE generate the proper SAS steps.

The process would change.  Instead of accumulating all the tests, each current iteration would generate one test.

Does this make any sense?

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 2870 views
  • 7 likes
  • 4 in conversation