BookmarkSubscribeRSS Feed
RichardDeVen
Barite | Level 11

Attempts at coding economy can lead you astray.

 

In the following why does the loop continue past 'g' ?

data _null_;
  length message $200;

  do s='a','b','d','g','x','y','z' until (not missing(message));

    message = ifc (s='g','Hey, s reached ' || s,'');

    msg_is_not_missing = not missing(message);

    put s= msg_is_not_missing= message=;
  end;
run;

Which logs

s=a msg_is_not_missing=0 message=
s=b msg_is_not_missing=0 message=
s=d msg_is_not_missing=0 message=
s=g msg_is_not_missing=1 message=Hey, s reached g    /* why does loop keep going */
s=x msg_is_not_missing=0 message=
s=y msg_is_not_missing=0 message=
s=z msg_is_not_missing=0 message=

Turns out the UNTIL applies only to the specification it is associated with, and DO can have multiple specifications separated by commas.

Reformatting the code so each specification is on its own line makes the reason/rule a little more clear:

do s = 'a'
, 'b'
, 'd'
, 'g' /* no until here */
, 'x'
, 'y'
, 'z' until (not missing(message))
;

To escape the loop according to initial expectations you would have to code inside the DO 

  if not missing (message) then leave;

 

SAS Help Center: DO Statement: Iterative 

5 REPLIES 5
andreas_lds
Jade | Level 19

I found this in the documentation:

In this example, the DO loop is executed when I=1 and I=2. The WHILE condition is evaluated when I=3, and the DO loop is executed if the WHILE condition is true.

do i=1,2,3 while (condition);
mkeintz
PROC Star

In the DO statement, commas prevail over while and until.  I initially found this a bit counterintuitive, but it has the great advantage of allowing distinct WHILE/UNTIL clauses for each of the comma-separated ranges:

 

data _null_;
  do i=1 to 3 until (i>=2), 101 to 103 while (i<=102), 1001 to 1003 while (i<1000),10001 to 10002;
    put i=;
  end;
run;

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
LeonidBatkhan
Lapis Lazuli | Level 10

Hi RichardADeVenezia,

According to SAS documentation for DO Statement: Iterative, "A WHILE or UNTIL specification affects only the last item in the clause in which it is located", in your case it is s='z'.

Hope this helps.

 

Tom
Super User Tom
Super User

The other way you could re-code is to switch from UNTIL() to WHILE().

do s = 'a'
     , 'b' while (missing(message))
     , 'd' while (missing(message))
     , 'g' while (missing(message))
     , 'x' while (missing(message))
     , 'y' while (missing(message))
     , 'z' while (missing(message))
;

Leaving the WHILE condition off the first makes work like the UNTIL() in an indexed loop: 

do i = 1 to 5 until (not missing(message));

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 487 views
  • 11 likes
  • 6 in conversation