Call a Macro With Each Observation In a Dataset

Reply
Occasional Contributor
Posts: 15

Call a Macro With Each Observation In a Dataset

[ Edited ]

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!

Respected Advisor
Posts: 3,001

Re: Call a Macro With Each Observation In a Dataset

[ Edited ]

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
Super User
Posts: 23,700

Re: Call a Macro With Each Observation In a Dataset

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!


 

Super User
Super User
Posts: 8,089

Re: Call a Macro With Each Observation In a Dataset

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 ;
Valued Guide
Posts: 565

Re: Call a Macro With Each Observation In a Dataset

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

Super User
Super User
Posts: 9,599

Re: Call a Macro With Each Observation In a Dataset

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.

Ask a Question
Discussion stats
  • 5 replies
  • 101 views
  • 2 likes
  • 6 in conversation