/* consecdays.sas Daniel Brockman 070723 Supplies dates missing from input. */ * tested at 070729; %macro consecdays(iset, oset, Dv) ; /* * iset = name of input data set * oset = name of output data set * Dv = name of SAS datevalue variable * * Notes: * 1. (intentionally deleted) * 2. oset will contain one observation for each day, whether or * not iset contains an observation for that day. * 3. oset will contain no date earlier than the earliest date in iset. * 4. oset will contain no date later than the latest date in iset. * 5. consecdays executes data steps and proc contents. * 6. Variable names in iset which contain "consecdays" as the first * characters may interfere with the correct function of this program. * * Notes for future enhancements: * 1. Consider using %findavar to avoid collisions among variables. 070805 * */ * get list of vars in iset ; %global greturn greturn1; %mkvarlist2(&iset) ; %let varlist=&greturn ; * list of vars ; %let varn=&greturn1 ; * number of vars ; * create unique and highly unlikely variable names for internal vars ; %let root=con; %let prev=&root.prev; %let SvDv=&root.SvDv; %let diff=&root.diff; %let i=&root.i; %let j=&root.j; %let k=&root.k; data &oset (keep= &varlist) ; * dropping intermediate vars; set &iset ; /* * Note: Storing datastep variable names in macro variables * gives this macro generality it wouldn't otherwise have. * Using hardcoded names for intermediate variables risks * interfering with the names of variables in the input data * set, the names which we know not. So most of these statements * are data step statements formed by the values of macro * variables. */ &prev = lag1(&Dv) ; * previous value of datevalue &Dv ; &diff = &Dv - &prev ; * num of days between curr obs and prev; if (&diff > 1) then do ; * more than 1 day of difference? ; /* make missing the vars */ %do L=1 %to &varn ; %let Lv=%scan(&varlist,&L) ; Sv_&root.&Lv=&Lv ; /* save the current value */ &Lv=.; %end; &Dv = &prev ; * set &Dv equal to previous obs ; do &i = 1 to (&diff - 1) ; * loop the missing dates ; &Dv = &Dv + 1 ; * increment date ; output ; * set vars to missing except Dv ; end; * end do &i ; /* restore the vars */ %do L=1 %to &varn ; %let Lv=%scan(&varlist,&L) ; &Lv=Sv_&root.&Lv ; %end; end; * if &diff ; output ; run; %mend consecdays;