BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
SAS_inquisitive
Lapis Lazuli | Level 10

I understand the concept of nesting %do loop such as below code.  However, there is a macro in SESUG paper where do loop has been nested in %do loop. I have hard time understanding this. (link of the paper: http://analytics.ncsu.edu/sesug/2002/ST02.pdf)

if the link does not work, the name of the paper is " A SAS® Program for the Computation of the Crude, Stratified and Mantel-Haenszel Odds Ratio in Case-Control Study Data Analysis of Nx2xK Tables ".

 

%macro mac;
  %do i= 1 %to 2;
     %do j= 1 %to 3;
	    data dat&i.&j.;
		  set sashelp.class(obs=5);
		run;
   %end;
  %end;
%mend mac;
%mac

Part of the macro that I am interested in:

 

....................
%do i=1 %to &en-1;
do j=1 to tottable;
cells{4+((&i-1)*4)}=cells{4+((&i-1)*4)} + colnum{((j-1)*(&en*2))+(&en+1+&i)};
cells{1+((&i-1)*4)}=cells{1+((&i-1)*4)} + colnum{((j-1)*(&en*2))+1};
cells{2+((&i-1)*4)}=cells{2+((&i-1)*4)} + colnum{((j-1)*(&en*2))+(1+&i)};
cells{3+((&i-1)*4)}=cells{3+((&i-1)*4)} + colnum{((j-1)*(&en*2))+(&en+1)};
end;
%end;
...............

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

No, no simple examples.  In fact, I don't think I've ever seen anybody do this before.  So Reeza might be entirely right, there might be another way to code this that doesn't look so involved.

 

At any rate, here's a simpler example.

 

Suppose your IRA contains $2,000 and you want to figure out how much it will be worth in the future.

 

Assume interest rates are 5% for the first 4 years, 6% for the next 4 years, 7% for the next four years, etc.

 

That might not be realistic, but at least it sets the stage for an example.  Without macro language you might code:

 

total=2000;

do year=1 to 4;

   total = total * 1.05;

   output;

end;

do year=1 to 4;

   total = total * 1.06;

   output;

do year=1 to 4;

   total = total * 1.07;

end;

 

You could use macro language to generate the same SAS code:

 

%do j=1 %to 3;

do year=1 to 4;

   total = total * %sysevalf(1.04 + 0.01 * &j);

   output;

end;

%end;

 

The macro language loop repeats the DATA step code, with slight changes each time depending on &J.

View solution in original post

10 REPLIES 10
Reeza
Super User

It looks to be embedded in a data step? Wouldn't the code below be the same?

 

en=&en;

do i=1 to en-1; do j=1 to tottable; cells{4+((i-1)*4)}=cells{4+((i-1)*4)} + colnum{((j-1)*(en*2))+(en+1+i)}; cells{1+((i-1)*4)}=cells{1+((i-1)*4)} + colnum{((j-1)*(en*2))+1}; cells{2+((i-1)*4)}=cells{2+((i-1)*4)} + colnum{((j-1)*(en*2))+(1+i)}; cells{3+((i-1)*4)}=cells{3+((i-1)*4)} + colnum{((j-1)*(en*2))+(en+1)}; end; end;

 

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

You have to remember that macro is just a text generation tool.  So to work out what is going on you could just copy and replace variables yourself, e.g. this code gets generated each time, with the mavro variables replaced each time incrementaly:

	    data dat1.1;
		  set sashelp.class(obs=5);
		run;
	    data dat1.2;
		  set sashelp.class(obs=5);
		run;

Etc. as many times as the two loops run, so j gets looped 3 times, once for each i value.

 

The real question however, is why would you want to do this in the first place.  It makes coding harder to split data up into lots of datasets, keep it in one, and use by group processing, arrays or joins to manipulate the data.

 

 

 

SAS_inquisitive
Lapis Lazuli | Level 10
@RW9. That was just the mock example of nesting %do loop. The main meat of question was if do loop can be nested in %do loop. Thanks !
RW9
Diamond | Level 26 RW9
Diamond | Level 26

I am not sure I am following you well.  You can create, from macro - which generates text - any valid SAS syntax.  So maybe you mean something like:

 

%macro tmp;
  %do i=1 to 2;
    do j=1 to 3;
      output;
    end;
  %end;
%mend;

data want;
  set have;
  %tmp;
run;  

What this does is replace the macro call %tmp, with the resolved text string.  The text that is generated is based off the macro code given, so it loops twice generating two do loops, the final code looking like:

 

 

data want;
  set have;
  do j=1 to 3;
output;
end;
do j=1 to 3;
output;
end; run;

 

That really is all macro language is, a way of generating code, you can nestle structures - %if's %do's etc. they operate in the same way as a datastep, but instead of data manipulation, your generating a text string.

 

Astounding
PROC Star

What does it do?  That part is relatively easy to explain.  It takes this code and repeats it:


do j=1 to tottable;
cells{4+((&i-1)*4)}=cells{4+((&i-1)*4)} + colnum{((j-1)*(&en*2))+(&en+1+&i)};
cells{1+((&i-1)*4)}=cells{1+((&i-1)*4)} + colnum{((j-1)*(&en*2))+1};
cells{2+((&i-1)*4)}=cells{2+((&i-1)*4)} + colnum{((j-1)*(&en*2))+(1+&i)};
cells{3+((&i-1)*4)}=cells{3+((&i-1)*4)} + colnum{((j-1)*(&en*2))+(&en+1)};
end;

 

Each repetition uses a different value for &i.

 

The number of repetitions is &en-1. 

 

Why is this useful?  I'm not sure I can answer that.  But the author of the paper thinks it's the right thing to do.

 

Good luck.

SAS_inquisitive
Lapis Lazuli | Level 10

@Reeza@RW9@Astounding.  Thanks for the explanation.  The macro is relatively large so it is hard to understand the author's intution. Is there relatively small and simple  exmaple where do loop is nested in % do loop?

Reeza
Super User

If those variables weren't in an array and you need to dynamically determine the number of variables then a %do loop would have made sense.

Astounding
PROC Star

No, no simple examples.  In fact, I don't think I've ever seen anybody do this before.  So Reeza might be entirely right, there might be another way to code this that doesn't look so involved.

 

At any rate, here's a simpler example.

 

Suppose your IRA contains $2,000 and you want to figure out how much it will be worth in the future.

 

Assume interest rates are 5% for the first 4 years, 6% for the next 4 years, 7% for the next four years, etc.

 

That might not be realistic, but at least it sets the stage for an example.  Without macro language you might code:

 

total=2000;

do year=1 to 4;

   total = total * 1.05;

   output;

end;

do year=1 to 4;

   total = total * 1.06;

   output;

do year=1 to 4;

   total = total * 1.07;

end;

 

You could use macro language to generate the same SAS code:

 

%do j=1 %to 3;

do year=1 to 4;

   total = total * %sysevalf(1.04 + 0.01 * &j);

   output;

end;

%end;

 

The macro language loop repeats the DATA step code, with slight changes each time depending on &J.

Tom
Super User Tom
Super User

There is no real advantage in that particular loop of coding the outer loop as a macro %DO loop instead of just using a data step DO loop. This is because the value being iterated over is just integers and the integers are just being used in calculations. So you could just do the same thing with a numeric variable in a data step DO loop.

 

The point where using a %DO loop becomes useful is when you are using the macro variables to generate different code elements like variable names that the DATA step needs to know before it starts.  Whether the code you are generatng inside the %DO loop contains a data step DO loop depends on what you need to do.

 

There are other %DO loops in that paper where the macro variable is used as part of a variable name in the generated code. In that case it might be more difficult to convert to a struture that did not use a macro %DO loop.  But you probably could do the same thing with an ARRAY instead and just use a data step DO loop to index over the array of variables.

 

 

 

SAS_inquisitive
Lapis Lazuli | Level 10

Thank you all.  

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 10 replies
  • 5221 views
  • 3 likes
  • 5 in conversation