/* trimset.sas D. Brockman 070730 remove leading and trailing missing obs. */ * tested 070730 ; %macro trimset(iset,oset,vlist); /* * iset = input set * oset = output set * vlist = list of selected vars separated by spaces. * * trimset returns in global macro var greturn the number of obs in oset. * * trimset deletes from the dataset any leading or trailing observations * for which all the vars in vlist have missing values. trimset doesn't * remove the all-missing obs if there is a preceding observation with * some of these values not missing and if there is a subsequent observation * with some of these values not missing. * * Take care to assure an appropriate sort order of the input data set. * * Lore: Inspired by a data set that, through intended calculations, * surprisingly turned out to have many initial observations * missing for variables of interest, though uselessly present in the data set. * */ %global greturn ; %let dsid=%sysfunc(open(&iset)); %let nobs=%sysfunc(attrn(&dsid,nobs)); %let rc=%sysfunc(close(&dsid)); %let fkeep=%eval(&nobs+1); * init first record to keep; %let Lkeep=0; * init first record to keep; * count the vars in our list ; %let nv=0; * init count; %do %while(%scan(&vlist,%eval(&nv+1)) ne ) ; * loop the vars ; %let nv=%eval(&nv+1); * incr count ; %end ; * end loop the vars ; %if (&nobs gt 0 ) %then %do ; * if at least one obs in iset ; data _null_ ; set &iset ; retain fkeepL4L LkeepL4L; * dont lose values found ; array varsL4L[&nv] &vlist ; * set array on our var list ; if (_N_=1) then do ; * only on first iteration ; fkeepL4L=&fkeep ; * number of first observation to keep ; LkeepL4L=&Lkeep ; * number of last observation to keep ; end ; missL4L=1 ; * assume all missing ; do iL4L=1 to &nv ; * loop the var list ; missL4L=missing(varsL4L[iL4L]) ; * is it missing? ; if (not missL4L) then leave; * we found a value ; end; * end loop the var list ; if ( (not missL4L) and (fkeepL4L>_N_) ) then fkeepL4L=_N_ ; * first ?; if ( (not missL4L) and (LkeepL4L<_N_) ) then LkeepL4L=_N_ ; * Last ?; call symput('fkeep',fkeepL4L) ; * number of first some-not-missing obs; call symput('Lkeep',LkeepL4L) ; * number of Last some-not-missing obs; run; %end; * end if nobs > 0 ; data &oset ; * create output set; set &iset (firstobs=&fkeep obs=&Lkeep) ; run; %let greturn=%eval(&Lkeep-&fkeep+1); * number of obs in oset; %mend trimset ;