BookmarkSubscribeRSS Feed
yus03590
Calcite | Level 5

Hi!

 

    I've got a problem where I need to loop through observation in a dataset and call a macro with each observation.

Here is an example dataset:

data work.schedule; 
input id 8. nm $20. senddays $14.;
datalines4;
2013312	México              3
2010941 Ghana               5
2013320 England             1
2013398 Argentina           5
2013363 Philippines         2
2013789 Spain               3
;;;;
run;

Each set of id, nm and senddays are parameters in a macro call.  For example:

%macro doStuff(id=,nm=,sendday=);
/* calculate stuff, run procedures, etc */
%mend doStuff;

/* pseudocode that I need to achieve*/

%macro main; %do for each observation i in work.schedule; %doStuff(i.id,i.nm,i.sendday); end;

%mend main;


%main

How do I do this in SAS?  Does it have to be done in a %do loop inside a macro or is there another way?

 

Thanks!

6 REPLIES 6
PaigeMiller
Diamond | Level 26

You can create macro variables inside a data step using CALL SYMPUTX, and then after assigning the value of the country name to the maacro variable, you can run your macro %dostuff. UNTESTED CODE, assumes you have computed or know the number of observations in your data set, and this is the value of macro variable &nobs

 

%macro do_all;

%do i=1 %to &nobs;
    Data _null_;
        Set have(firstobs=&i obs=&i);
        call symputx('nm',nm);
        Call symputx('id',id);
        Call symputx('senddays',senddays);
    run;
    %dostuff(id=&id,nm=&nm,sendday=&senddays)
%end;

%mend;
%do_all

 

Or you can do this via CALL EXECUTE, but I'll let someone else describe that code.

--
Paige Miller
cameronmuir
Calcite | Level 5
thanks for this, very helpful!
Reeza
Super User

CALL EXECUTE is designed for this and pretty straightforward. You need to make a string that has the values you need and basically looks like your macro call, 

 

%doStuff(id=201312 , nm=Mexico, sendday=3);

You can use CATT() to create the string and then use CALL EXECUTE to execute the string. I've commented it out below, but you can uncomment and run it. Additionally, if you don't need the intermediary data set change the run_macros to _null_. 

 

data run_macros;
set schedule;

str = catt('%doStuff(id=', 
            id, 
            ', nm=',
            nm,
            ', sendday=', 
            senddays, 
            ');');
*call execute (str);

run;

 


@yus03590 wrote:

Hi!

 

    I've got a problem where I need to loop through observation in a dataset and call a macro with each observation.

Here is an example dataset:

data work.schedule; 
input id 8. nm $20. senddays $14.;
datalines4;
2013312	México              3
2010941 Ghana               5
2013320 England             1
2013398 Argentina           5
2013363 Philippines         2
2013789 Spain               3
;;;;
run;

Each set of id, nm and senddays are parameters in a macro call.  For example:

%macro doStuff(id=,nm=,sendday=);
/* calculate stuff, run procedures, etc */
%mend doStuff;

/* pseudocode that I need to achieve*/

%macro main; %do for each observation i in work.schedule; %doStuff(i.id,i.nm,i.sendday); end;

%mend main;


%main

How do I do this in SAS?  Does it have to be done in a %do loop inside a macro or is there another way?

 

Thanks!


 

Tom
Super User Tom
Super User

That is a good example of where using a PUT statement to write the code can be very easy.

Especially if you fix the variable names in your metadata table to match the parameter names used by your macro.

data work.schedule; 
input id 8. nm $20. sendday $14.;
datalines4;
2013312	México              3
2010941 Ghana               5
2013320 England             1
2013398 Argentina           5
2013363 Philippines         2
2013789 Spain               3
;;;;
run;

filename code temp;
data _null_;
  set work.schedule ;
  file code ;
  put '%doStuff(' id= ',' nm= ',' sendday= ');';
run;
%include code / source2 ;
andreas_lds
Jade | Level 19

Depending on the SAS version you have, you could use the function dosubl in an data-step to execute a macro.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Call execute is probably the simplest way.  What I would suggest however is to check what you want to do.  Sometimes, not always, it is possible to re-write the code slightly in order to use by grouping rather than go through the whole macro creation and call with each set of parameters.  For instance, if the first datastep or proc in your macro filters out data based on the parameters then I can pretty much guarentee you that replacing the macro and setting the steps to us by group processing will be both simpler coding, faster operation, and less storage.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 14658 views
  • 4 likes
  • 7 in conversation