Hi!
SAS has a long chapter about compilation and execution but I have problems understanding the distinction between executions and iterations in the DO LOOP.
On page 117 the prep guide 9.4 says:
Each loop (or cycle of execution) is called an iteration.
It provides the following sample on page 212:
data work.earnings;
amount=1000;
rate= 0.75/12
do month=1 to 12;
earned+(amount+earned)*rate;
end;
run;
After the 12th execution of the DO loop, the value of month is incremented to 13. Because 13 exceeds the stop value of the iterative DO statement, the DO loop stops executiong, and processing continues to the next DATA step statement. [...] Only one observation is written to the data set.
-> said observation's value for the iteration variable month is 13.
In the quiz section one questions refers to the program above and asks about the number of times the do loop executes. Answer:
The number of iterations is determined by the DO statement's stop value, which in this case is 12.
I don't understand this solution; in my opinion it contradicts the previous paragraph. According to that I would have guessed the number is 13.
Another question about that topic uses this program:
data work.invest;
do year= 1990 to 2004;
capital+5000;
output;
end;
run;
So, if the stop value determines the number of iterations then the last year should be 2004, I think? But then again the paragraph at the top states that it would increment to 2005, stop and print 2005. That's also the answer in the appendix.
What am I missing? I guess I'm confusing something. Could it be that the iterations are only counted as complete cycles and executions by the number of times they start? So in the example of earnings program we have 12 complete iterations but start 13 executions?
Nice and clear question. But yes, you are confusing something 🙂
Each time the do loop in the second example iterates, the month variable increments by 1. When the loop has iterated 12 times the value increments from 12 to 13. 13 is outside the range of values the do loop will loop over, so the data step does not execute the loop again and processing proceeds after the loop. And after the loop, the month variable has the value 13.
Run this code and check the log. This might help you understand the logic.
data work.earnings;
amount=1000;
rate= 0.75/12;
do month=1 to 12;
earned+(amount+earned)*rate;
put "Inside loop: " month=;
end;
put "Outside loop: " month=;
run;
Thank you! The distinction between inside and outside the loop helped me a bit. In your example, the first put statement gives me the values 1-12 like I would expect. The outside loop just increments from 12 to 13 but it doesn't do anything to the other values. So I guess that just means that the loop executed a 13th time but since the limit was crossed it didn't do anything to the data?
Hello,
After the loop has been executed for month=12, the instruction
do month=1 to 12;
increases month to 13. Since 13>12, the code inside the loop is not
executed and the next instruction after the END statement is read.
The point they are trying to get at is the difference between how many times the iteration variable (loop counter) is incremented versus how many times the statements inside the DO/END block runs (executes).
The way an iterative DO loop (do i=1 to 10) works is that it increments the loop counter and then tests if the value exceeds the upper limit. Try DO i=1 to 4 by 2 and see that happens.
@CC_J :
The number of executions is the number of times the body of the loop (i.e. the program statements between DO and END) is executed. The number of iterations is the number of times program control passes through the body of the loop. Thus, both are exactly equal.
Whether the value of the iteration variable, i.e. the loop index, exceeds the TO value after the loop is exited depends on how the loop is organized internally. The way the iterative DO loop is organized in SAS, the index variable is incremented at the bottom of the loop and then the internal logic checks whether it now exceeds the TO value. If yes, program control exits the loop; otherwise, it is passed to the top of the loop again. Run the following step and look at the log; hopefully, it will give you a clearer idea of what is going on:
data _null_ ;
FROM = 1 ;
TO = 3 ;
/* Internal logic */
x = FROM ;
do until (0) ; /* until(0) or while(1) means "iterate forever" */
put "Execute # " x ;
x = x + 1 ;
if x > TO then goto exit ;
end ;
exit:
put x= / ;
/* Equivalent to: */
x = FROM ;
do until (0) ; /* until(0) or while(1) means "iterate forever" */
put "Execute # " x ;
x = x + 1 ;
if x > TO then leave ;
end ;
put x= / ;
/* Equivalent to: */
x = FROM ;
do until (x > TO) ; /* Due to UNTIL, x > TO condition is checked at the bottom of the loop */
put "Execute # " x ;
x = x + 1 ;
end ;
put x= / ;
/* Equivalent to: */
do x = FROM to TO ;
put "Execute # " x ;
end ;
put x= ;
run ;
If you're rather keenly interested in the anatomy of the DO loop and many of its curious variations, I'd suggest that you read this:
http://support.sas.com/resources/papers/proceedings13/126-2013.pdf
Kind regards
Paul D.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.