Date: Thu, 4 Sep 2008 10:54:29 -0700
Reply-To: "Choate, Paul@DDS" <pchoate@DDS.CA.GOV>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Choate, Paul@DDS" <pchoate@DDS.CA.GOV>
Subject: Re: Conditionally iterate data step until condition is met
In-Reply-To: A<98634D42B37B2E4E96CF3A3BD3CD9AE6026728AC@EX1VS2.nyced.org>
Content-Type: text/plain; charset="us-ascii"
Thanks Scott - but I don't see how this tests the number of observations
against a prior iteration and then exits if the same.
The problem is that the macro is executed and writes the data step code
before the data steps run, and so as far as my limited understanding
goes, the NObs generated during the datastep execution can't be used to
control the macro that writes it.
I was thinking a recursive call execute (if that is possible) might be
able or maybe a DoW loop that conditionally loops based on the NObs
comparison.
Paul Choate
DDS Data Extraction
(916) 654-2160
-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
Bucher Scott
Sent: Thursday, September 04, 2008 10:28 AM
To: SAS-L@LISTSERV.UGA.EDU
Subject: Re: Conditionally iterate data step until condition is met
Would something like this work?
%do %while %eval(&nobs < 100000);
[data step]
%let dsid = %sysfunc(open(rates));
%let nobs = %sysfunc(attrn(&dsid, NOBS));
%let rc = %sysfunc(close(&dsid));
%end;
Regards,
Scott
-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
Choate, Paul@DDS
Sent: Thursday, September 04, 2008 12:51 PM
To: SAS-L@LISTSERV.UGA.EDU
Subject: Conditionally iterate data step until condition is met
Every once in a while I need to repeatedly run a data set through a data
step with a set of conditions until the set stabilizes at a certain
previously unknown record count. Usually when winnowing down a pool of
messy data to the best available set using a date criteria.
Typically I wrap the data in a macro and set a %do %until counter based
on a previously generated nobs or other count, such as a maximum record
count across certain by-groups in the data. For example:
data _null_;
set rates nobs=nobs;
by vendor svscd sub FY;
if first.FY then count=0;
Count+1;
if last.FY then Num=max(count,Num);
if _n_=nobs then call symput('Num',put(Num,8.));
run;
%macro repeat;
%do i=1 %to %eval(&Num);
data rates;
set rates;
by vendor svscd sub FY Date_Received Beginning_Eff_Date
Ending_Eff_Date;
if last.FY and not first.FY and
(Ending_Eff_Date>mdy(6,30,2000+input(FY,2.))) then delete;
run;
%end;
%mend repeat;
%repeat
But the criteria may be met before the last loop and so it chews through
the data an unnecessary number of times.
What I would like to do is not use a previously determined cut off, but
to instead check the number of observations after each iteration and
exit the loop if it hasn't changed. Maybe with call execute, maybe
macro loops, maybe DoW loops. I have come up with one idea for a kludge
but it's ugly and I would like something succinct.
Any thoughts?
Paul Choate
DDS Data Extraction
(916) 654-2160