Help using Base SAS procedures

Do Until Loop question

Reply
New Contributor
Posts: 4

Do Until Loop question

The table claims2_x has 6 rows 1 where the prov = 015 and 1 where the prov is 044 both have value = 80, the remaining rows have other prov values. The results are returning both rows while I only want the 015 row to return. I thought that the do until loop would end after the found condition was true?

Any insight would be helpful.

Thanks

Michael

data radv.claims4(drop= _type_ _freq_ x pcp_id);
set radv.claims2_x;
found = 0;
do found=1 until (found);
if suspected_value = ('80') and prov = ('015')
then do; id = bill ; output; found = 1 ; end;
else if suspected_value = ('80') and prov = ('296')
then do; id = bill ; output; found = 1 ; end;
else if suspected_value = ('80') and prov = ('044')
then do; id = bill; output; found = 1 ; end;
end;
run;
SAS Super FREQ
Posts: 8,864

Re: Do Until Loop question

Hi:
I'm not sure why you need a DO UNTIL Loop if you only want the row where PROV = '015'. The Data step automatically loops to read every observation (or row) from your input file (on the SET statement).

Here are some alternative possibilities. This code uses SASHELP.CLASS which only has 19 rows and there are 3 different techniques illustrated to create a simple report where rows meet a condition; or create a data set if rows meet a condition:
1) Use a simple WHERE statement in PROC PRINT (if all you want is a report)
[pre]

**1) Use a Where statement;
proc print data=sashelp.class;
title '1) Use WHERE Stmt: Girls Over 14';
where sex = 'F' and age gt 14;
run;

[/pre]
2) Create a file with just the subset you want
[pre]
**2) Make a temp file;
data girls_over_14;
set sashelp.class;
if sex = 'F' and age gt 14 then output;
run;

proc print data=girls_over_14;
title '2) Create Temp File: Girls Over 14';
run;
[/pre]

3) Create 2 files in your DATA step program, one for the subset you want and one for ALL obs (possibly creating some kind of newvariable)
[pre]

**3) Make a temp file for 14 yr olds and
another file for all the obs;

data girls14(keep=name age sex height weight)
everybody(keep=name age height sex newvar);
set sashelp.class;
if sex = 'F' and age gt 14 then output girls14;

newvar = age*height;
output everybody;
run;

proc print data=girls14;
title '3) Create Temp File: Girls Over 14';
run;

proc print data=everybody;
title '3) Everybody with new variable';
run;

[/pre]


If you feel that you still need a DO UNTIL Loop then you might consider contacting Tech Support for more help with the program design. They can look at your data and your logic and make suggestions as to the best approach.

cynthia
New Contributor
Posts: 4

Re: Do Until Loop question

Posted in reply to Cynthia_sas
Cynthia,

Thanks for reviewing by code. The reason that I am attempting to use a do until loop is that I have a table where mulitple rows could return matches to my criteria and I only want the results of the 1st row that matches my criteria to be returned.

So from my example I only want id = bill if the suspected value is 80 and the prov is 015. Currently I am also getting a row where the suspected value is 80 and the prov is 044, because it matches my criteria.

My goal is to have a process that checks multiple conditions and selects the first row if it mathches the criteria and then end the program or proceed to the next row etc.

Michael
New Contributor
Posts: 4

Re: Do Until Loop question

Posted in reply to Cynthia_sas
Cynthia,

Thanks for reviewing by code. The reason that I am attempting to use a do until loop is that I have a table where mulitple rows could return matches to my criteria and I only want the results of the 1st row that matches my criteria to be returned.

So from my example I only want id = bill if the suspected value is 80 and the prov is 015. Currently I am also getting a row where the suspected value is 80 and the prov is 044, because it matches my criteria.

My goal is to have a process that checks multiple conditions and selects the first row if it mathches the criteria and then end the program or proceed to the next row etc.

Michael
SAS Super FREQ
Posts: 8,864

Re: Do Until Loop question

Hi:
There's a big difference between ending the program and checking the rest of the rows.

But there's still a way to get only the first obs that meets your criteria by setting flags -- don't need a DO UNTIL loop. In this example, the GETFIRST data set only contains 1 obs -- for the first girl whose age was GT 14. The CKFLAGS data set is all the observations and the flags, so you can see the behavior of the FRSTGIRL flag for this one condition across all obs.

[pre]
**4) get the first of the criteria;
data getfirst ckflags;
set sashelp.class;
** frstgirl is the flag for whether ;
** the first girl was found;
** I want to retain this flag;
retain frstgirl 0;

** Only proceed to inside test if
frstgirl is still 0;
if frstgirl = 0 then do;
if sex = 'F' and age gt 14 then do;
frstgirl=1;
output getfirst;
end;
end;

output ckflags;
run;

proc print data=getfirst;
title '4) Get First Obs that meets criteria';
title2 'should only be 1 obs in this file';
run;

proc print data=ckflags;
title '4) See the status of all the flags using this logic';
title2 'The output performed on the obs when frstgirl flag changed from 0 to 1';
run;

[/pre]

I chose to output to a data set rather than end the program (stop reading the file) because if you have other criteria or other tests, then you may want to include flags for those tests. If you needed to test multiple criteria (such as getting the first female student where AGE GT 14 and the first male student where AGE GT 14) then you'd need more flags:
[pre]
**5) get the first of the criteria;
data multcriteria allflags;
set sashelp.class;

retain frstgirl frstguy 0;

if frstgirl = 0 then do;
if sex = 'F' and age gt 14 then do;
frstgirl=1;
output multcriteria;
end;
end;

if frstguy = 0 then do;
if sex = 'M' and age gt 14 then do;
frstguy=1;
output multcriteria;
end;
end;

output allflags;
run;

[/pre]

There are, no doubt, other solutions to the problem, but this to me, is the most straightforward without using DO loops, because it takes advantage of the fact that each obs is read only 1 time and tested against the criteria and then flags are set that control whether subsequent obs need to be tested at all -- for this criteria. Output is controlled for every obs based on the status of the flags and only happens inside the IF statement for each test. If an obs could satisfy more than one test, then this logic might not be appropriate and you might need to use ELSE and/or decide where to control the output differently.

The CKFLAGS and ALLFLAGS data sets are really included in the code for instructional purposes so that you can print out the whole dataset to see how the flags were set for every obs.

cynthia
Ask a Question
Discussion stats
  • 4 replies
  • 201 views
  • 0 likes
  • 2 in conversation