BookmarkSubscribeRSS Feed
imdickson
Quartz | Level 8

Hi everyone. I am trying to understand more about DO Loop such as Do while, Do until and RETAIN.

What I want to know more is that the Counter for Do loop is not assigned in the code. 

For example:

data carloan_until;
 /*loan = 30000;*/
 payments = 0;
 
 do until (loan = 0);
  loan = loan - 500;
  payments = payments + 1;
 end;
run;

As you can see, i commented LOAN out and hence LOAN variable is not defined in anywhere of the script. When i run the script, the DO LOOP run forever. What is the value of LOAN when it is not assigned? if it is NULL/MISSING, it will cause infinite loop? Why do i run into infinite loop?

 

As for RETAIN, If it is just a simple data step like below:

data test;
retain LOAN;
set a;
LOAN=500;
run;


data test2;
set a;
retain LOAN;
LOAN=500;
run;

 

What is the value of LOAN in test and test2?

 

Yes I know i can run them in my BASE SAS but i would like to know the value behind it. Don't get me wrong, i did spend some time reading guides online but I am just curious on the behaviour when we do not assign any value before hand.

 

 

10 REPLIES 10
PeterClemmensen
Tourmaline | Level 20

1) Yes. loan is missing when it is not assigned a value. And when you subtract a value from a missing value, the result will be missing. See the small example below. This is also te reason that your Do Until loop is infinite. At the bottom of each iteration of the loop, SAS checks if the condition in parenthesis (loan=0) is true. This does not happen, because the value of loan will always be missing.

 

data _null_;
   put loan=;
   loan=loan-500;
   put loan=;
run;

2) The value of Loan is both test and test2 is 500 for each observation, because you set it yourself at the end of the data step.

Astounding
PROC Star
One additional suggestion for avoiding infinite loops:

When using DO WHILE or DO UNTIL, use an inequality to end the loop. For example, this is dangerous:

do until (loan = 0);

This is much less likely to produce an infinite loop:

do until (loan <= 0);
imdickson
Quartz | Level 8

@Astounding  @PeterClemmensen 

Can i understand this way.

 

For DO Loop, the only difference between WHILE and UNTIl is that WHILE is evaluated the statement before executing while UNTIL is evaluated after the whole loop ends. Therefore, UNTIL is best using = while WHILE is best using < or > ?

Kurt_Bremser
Super User

Do until will always go through at least one iteration, while a do while may terminate immediately without executing the loop body at least once.

 

In both cases, the loop (while) or termination (until) condition needs to be formulated with care to avoid infinite loops.

Astounding
PROC Star

No!

DO WHILE ends when its condition becomes false. It is your responsibility to make sure that the condition eventually becomes false.

DO UNTIL ends when its condition becomes true. It is your responsibility to make sure that the condition eventually becomes true.

In both cases, use inequality (including >= or <=) to improve the chances of avoiding an infinite loop.

 

Here's a case in point, an infinite loop:

 

data carloan_until;
 loan = 3100;
 payments = 0;
 do until (loan = 0);
   loan = loan - 500;
   payments = payments + 1;
 end;
run;

With a starting point of 3100, LOAN will never be 0.  But it will get to below zero.  Changing < to <= will cause the loop to end.

imdickson
Quartz | Level 8

@Astounding @Kurt_Bremser 

Thanks for your explanation. Appreciate it.

 

I also come across another DO WHILE loop and this got me confused again.
The result of n is 6. But why? Do While evaluate the condition before executing. Initially, n=1 and it will not loop. I was expecting n is 7 since the condition is (n lt 6) which comes to my mind is 7. What is the reason behind it?

 

data test;
n=1;
do while(n lt 6);
n+1;
end;
run; 

 

Astounding
PROC Star

DO WHILE checks the condition at the top, as you indicated.  However, it performs the loop as long as the condition is TRUE.

 

You can test some of the actions yourself, by adding PUT statements to the DATA step:

 

data test;
n=1;
do while(n lt 6);
n+1;
put "Inside:  "  n=;
end;
put "Outside:  " n=;
run; 
imdickson
Quartz | Level 8

Thanks for the info. If i understand correctly, the reason why n is 6 is due to:

 

1) The very last loop counter(n) is 5

2) The reason why n=5 counter but n is 6 at the end is because of n+1 in the loop of counter n=5. 

 

Hence the result is 6.

 

Do i understand correctly?

Astounding
PROC Star

That's correct.  One more piece to add to your thinking ...

 

Once n increases to 6, the loop is ALMOST over.  SAS checks the DO WHILE condition, and finds that it is false.  That's when SAS decides that the loop is over and should not execute again.

Kurt_Bremser
Super User

It will loop,as the while condition is met.

 

But since you are testing for less than instead of less or equal, the loop terminates as soon as n is incremented to 6.

 

Whenever you have such wonderings, put statements are great to clear up doubts:

data test;
n = 1;
cond = (n lt 6);
put "before: " cond=;
do while (n lt 6);
 n + 1;
 cond = (n lt 6);
 put "end of loop: " n= cond=;
end;
run; 

Run this code and take a close look at the log.

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