DATA Step, Macro, Functions and more

do loop nesting in %do loop

Accepted Solution Solved
Reply
Regular Contributor
Posts: 234
Accepted Solution

do loop nesting in %do loop

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;
...............

 


Accepted Solutions
Solution
‎02-10-2016 01:31 PM
Super User
Posts: 5,085

Re: do loop nesting in %do loop

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


All Replies
Super User
Posts: 17,840

Re: do loop nesting in %do loop

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;

 

 

Super User
Super User
Posts: 7,405

Re: do loop nesting in %do loop

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.

 

 

 

Regular Contributor
Posts: 234

Re: do loop nesting in %do loop

@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 !
Super User
Super User
Posts: 7,405

Re: do loop nesting in %do loop

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.

 

Super User
Posts: 5,085

Re: do loop nesting in %do loop

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.

Regular Contributor
Posts: 234

Re: do loop nesting in %do loop

[ Edited ]

@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?

Super User
Posts: 17,840

Re: do loop nesting in %do loop

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.

Solution
‎02-10-2016 01:31 PM
Super User
Posts: 5,085

Re: do loop nesting in %do loop

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.

Super User
Super User
Posts: 6,502

Re: do loop nesting in %do loop

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.

 

 

 

Regular Contributor
Posts: 234

Re: do loop nesting in %do loop

Thank you all.  

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 10 replies
  • 480 views
  • 3 likes
  • 5 in conversation