* wndo2.sas Daniel Brockman 070715 Selects series in a time window by date ;
%macro wndo2(iset,oset,Dv,Cal,d1,ndays);
/*
* iset = name of input data set
* oset = name of output data set
* Dv = name of variable, which is a SAS datevalue, and which
* is the date of the observation.
* Cal = If Cal = Y or y or Yes or yes, then ndays is the
* number of calendar days in the selected observations,
* such that d1 is the first, and the remaining observations
* in oset come from consecutive calendar days following
* d1. d1 is a SAS datevalue.
* If Cal is some other value, then ndays is the number of
* observations returned in oset, which are consecutive
* available observations. d1 is the first observation
* number to consider.
* d1 = meaning depends on Cal.
* ndays = number of days, a positive integer, with meaning dependent
* on Cal. If ndays isn't a positive integer, then
* the results of wndo2 are undefined.
*
* wndo2 will sort iset by Dv (ascending) before subsequent processing.
*
* wndo2 doesn't check iset for validity of values of Dv, nor for whether
* it has the appropriate data type, nor for any other characteristic.
*
* If Cal=Y, then oset will contain at most ndays observations. wndo2 selects
* only those observations occurring during the ndays consecutive calendar days
* that begin with d1. If an observation is missing for some day in this
* set, then its absence will reduce the number of observations returned in
* oset. If there are zero observations in the ndays consecutive calendar
* days beginning on d1, then oset will contain zero observations.
*
* If Cal<>Y, then oset will contain ndays observations.
*
* If iset contains fewer than ndays observations occurring on and after
* d1, then oset will contain no observations than those.
*
*/
%global greturn;
/* I discovered we had a collision with the var t1 in the calling program
* and so here we declare t1 local to avoid that trouble
*/
%local t1;
%getdsname(Twndo2); * get tempo data set name ;
%let t1=&greturn;
* sort in ascending order by var &Dv ;
proc sort data=&iset out=&t1;
by &Dv;
run;
/*
* If Cal = Y, calc end date of interval
* (http://support.sas.com/techsup/technote/ts668.html) ;
*/
%let Cal = %upcase(%substr(&Cal,1,1)) ;
%if ( &Cal eq Y ) %then
%let d2 = %eval(&d1-1+&ndays) ; * end date of interval ;
%findavar(&t1,ctr) ; * counter var ;
%let counter=&greturn ;
data &oset (drop=&counter);
set &t1 ; * sorted input ;
retain &counter 0 ; * init counter ;
* check for last observation to extract ;
%if ( &Cal eq Y ) %then %do ;
if &Dv >= &d1 ; * subset observations on or after &d1;
if &Dv <= &d2 ; * subset to end date ;
%put wndo2 L78 Cal:&Cal Dv:&Dv d1:&d1 d2:&d2 ;
%end ;
%else %do ;
if _N_ >= &d1 ; * subset observations on or after &d1;
&counter = &counter + 1 ; * increment counter ;
if &ndays >= &counter ; * subset to full count;
%put wndo2 L85 Cal:&Cal Dv:&Dv counter:&counter d1:&d1 ndays:&ndays N:_N_;
put &counter.= _N_= ;
%end ;
run;
* %delds(&t1); * remove tempo dataset ;
%mend wndo2 ;