BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
bzimmermann
Calcite | Level 5

Hello All,

I am having an issue with this bit of code. I have created a null dataset containing the variables required in the loop macro and it also counts the number of observations. I want to run through each of the lines in the control_var dataset through the loop macro. But when I run the code it runs only the last row in the control_var table, it doesn't start at the first row. If I remove the macro and have the do statement run using a title i variable in the log it works starting at 1 and going through the 19 observations. So I believe the %do clause is accurate. There is something wrong with calling the variables from the control_var table

Any help you can give me would be greatly appreciated-thanks

 
%MACRO run_loops();
data _null_;
set control_var;
call symput ("year_qtr", year_qtr);
call symput ("qtr", qtr);
call symput ("nobs",_n_);
run;
 
%DO i = 1 %TO &nobs;
%loop(qtr=&&qtr&i,year_qtr=&&year_qtr&i);
%END;
%MEND run_loops;
%run_loops();
1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

@bzimmermann wrote:

Hello All,

I am having an issue with this bit of code. I have created a null dataset containing the variables required in the loop macro and it also counts the number of observations. I want to run through each of the lines in the control_var dataset through the loop macro. But when I run the code it runs only the last row in the control_var table, it doesn't start at the first row.


Yes, that is how the data step works. For the first observation in data set CONTROL_VAR, it assigns &year_qtr the proper value based upon the first observation, and then on the second observation of data set CONTROL_VAR, it overwrites the value of &year_qtr to be correct for the second observation. And so on, until you get to the last observation of CONTROL_VAR, and it overwrites the value &year_qtr with the value on the last observation.  So then your DO loop only has that available, it doesn't have the value of the other observations available.

 

You might want to consider CALL EXECUTE as a way of calling a macro with parameters based upon the data set value on each record. That link has an example of calling a macro based upon the values of a data set variable on each record. Another option is to put the DATA _NULL_ into the loop, and execute it to get the macro variables for just one observation (the &i-th observation).

 

Depending on what %LOOP is doing (we don't know, you didn't show us the code), you might be able to simplify the whole thing to use a BY statement and get rid of the macros entirely.

--
Paige Miller

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

@bzimmermann wrote:

Hello All,

I am having an issue with this bit of code. I have created a null dataset containing the variables required in the loop macro and it also counts the number of observations. I want to run through each of the lines in the control_var dataset through the loop macro. But when I run the code it runs only the last row in the control_var table, it doesn't start at the first row.


Yes, that is how the data step works. For the first observation in data set CONTROL_VAR, it assigns &year_qtr the proper value based upon the first observation, and then on the second observation of data set CONTROL_VAR, it overwrites the value of &year_qtr to be correct for the second observation. And so on, until you get to the last observation of CONTROL_VAR, and it overwrites the value &year_qtr with the value on the last observation.  So then your DO loop only has that available, it doesn't have the value of the other observations available.

 

You might want to consider CALL EXECUTE as a way of calling a macro with parameters based upon the data set value on each record. That link has an example of calling a macro based upon the values of a data set variable on each record. Another option is to put the DATA _NULL_ into the loop, and execute it to get the macro variables for just one observation (the &i-th observation).

 

Depending on what %LOOP is doing (we don't know, you didn't show us the code), you might be able to simplify the whole thing to use a BY statement and get rid of the macros entirely.

--
Paige Miller
Tom
Super User Tom
Super User

I don't see where you made any attempt to create a macro variable named QTR1 or QTR2.

 

Do you see that anywhere?

Spoiler
data _null_;
set control_var;
call symputX(cats("year_qtr",_n_), year_qtr);
call symputX(cats("qtr",_n_), qtr);
call symputX("nobs",_n_);
run;

PS Do not use the ancient CALL SYMPUT() function unless there is a reason why you need to store leading and/or trailing spaces into the macro variable.

 

Tom
Super User Tom
Super User

Why bother making the macro variables at all?

 

Why not just generate the calls to %LOOP directly with SAS code?

 

For example by writing a program file and using %INCLUDE to run it.

Then you take advantage of the features of the PUT statement to make creating the code easier.

filename code temp;
data _null_;
  set control_var ;
  file code;
  put '%loop(' qtr= ',' year_qtr= ')' ;
run;
%include code / source2;
bzimmermann
Calcite | Level 5
Thank you all for your suggestions, I was able to use Paige's suggestion successfully.


data _null_;
set control_var;
call execute('%loop(qtr='||strip(qtr)||' ,year_qtr='||strip(year_qtr)||');');
run;

Quentin
Super User

Glad you got it working.  Please mark Paige's answer as correct / accepted, to close out this question.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 5 replies
  • 501 views
  • 0 likes
  • 4 in conversation