%macro tscsdata(version, in=_last_, out=, ts=, cs=, vars=, nreg=, keep=); %if &version ne %then %put TSCSDATA macro Version 2.1; %if &in=_last_ %then %let in=&syslast; %let notesopt = %sysfunc(getoption(notes)); options nonotes; * in = Names the input data set. last-created used by default. out = Names the output data set. ts = The variable in the input data set which identifies the time points cs = The variable in the input data set which identifies the cross sections vars = List of model variables with the response variable first followed by explanatory variables separated by spaces nreg = The number of explanatory variables keep = Binary variables (1=keep the observation for analysis by TSCSREG) Note: any obs in the IN= data set with a zero value for keep will necessarily have a zero for keep in the OUT= data set. *; /* Sort data appropriately for TSCSREG. */ proc sort data=&in out=&out; by &cs; run; data _null_; x=&nreg+1; call symput('nregp1',x); run; /* Set keep variable to zero for the observations with missing values for one or more of the model variables. */ data &out ; set &out end=_eof; if _n_ <1.5 then do; _message="Observations excluded due to missing model variable values:"; put _message; _count=0; end; array _x{&nregp1} &vars ; _miss=(nmiss(of &vars)>0.5); _miss=_miss*&keep; if _miss=1 then do; put " Obs=" _n_ " &cs=" &cs " &ts=" &ts; &keep=0; _count+1; end; if _eof then do; put "Number excluded due to missing values: " _count; put " "; end; drop _count _miss _message; run; /* Set the keep variable to zero for those cross sections with too few time points (i.e. 1 or 0). */ proc means data=&out noprint n; where &keep=1; by &cs; var &keep; output out=_temp(keep=&cs _n) n=_n; run; data &out; merge &out _temp end=_eof; by &cs; if _n_ <2 then do; _message= "Observations excluded due to too few time points for the cross section:"; put _message; _count=0; end; _temp=(_n<1.5)*(&keep=1); if _temp then do; &keep= 0; put " Obs=" _n_ " &cs=" &cs " &ts=" &ts; _count+1; end; if _eof then do; put "Number excluded due to too few time series values: " _count; put " "; end; drop _n _temp _message _count; run; /* Set the keep variable to zero for those time points with too few cross sections (i.e. 1 or 0). */ proc sort data=&out; by &ts &cs; run; proc means data=&out noprint n; where &keep=1; by &ts; var &keep; output out=_temp(keep=&ts _n) n=_n; run; data &out; merge &out _temp end=_eof; by &ts; if _n_ <2 then do; _message= "Observations excluded due to too few cross section values for a time point:"; put _message; _count=0; end; _temp=(_n<1.5)*(&keep=1); if _temp then do; &keep= 0; put " Obs=" _n_ " &cs=" &cs " &ts=" &ts; _count+1; end; if _eof then do; put "Number excluded due to too few cross section values: " _count; put " "; end; drop _n _temp _message _count; run; proc sort; by &cs &ts; run; options ¬esopt; %mend;