Electronic Appendix ************************************************************ * make_case_pt.sas - macros to arrange grouped Poisson data cells * with one line per stratum for conditional Poisson model * for CLR analysis using NLP or NLMIXED ************************************************************ * MACRO INPUT VARIABLES * Required: * indsn_pois - input poisson data set file * stratvars - variables that define the strata * cases - number of cases in the cell * pt - person-time in the cell * vlist - variables to output, separated by spaces * Optional: * outdsn - name of output data set (default=stratpois) ************************************************************ * OUTPUT VARIABLES: * stratvars - values of the strata variables * _stratno - stratum number for each unique cross classification * of the stratum variables * _ncovals - number of unique covariate values within the stratum * _totcases - total number of cases in the stratum * _totpt - total person time in the stratum * _z1,... - covariate values for the stratum * _cases1,... - cases at the corresponding covariate value * _pt1,... - person time at the corresponding covariate value ************************************************************ * NOTES: * 1) Information needed about the data, input data set name, * strata and analysis variables, and the maximum set size * are included in the data set label. * 2) strata with no cases or no person time are deleted * 3) covariate values with no person time are deleted ************************************************************ ; %macro makelist(list,pre,post); %* utility macro that appends various quantities in a list; %let nvars = 0; %do %until (%scan(&list,%eval(&nvars+1)) lt 0); &pre.%scan(&list,%eval(&nvars+1))&post %let nvars = %eval(&nvars+1); %end; %mend; %macro make_case_pt(indsn_pois,stratvars,cases,pt,vlist,outdsn=stratpois); %* get the number of variables in vlist; %let nvars = 0; %do %until (%scan(&vlist,%eval(&nvars+1)) lt 0); %let nvars = %eval(&nvars+1); %end; * give each stratum an number id; 1 proc sort data=&indsn_pois (keep=&stratvars &cases &pt &vlist) out=_temp1; by &stratvars; run; data _temp2; set _temp1; by &stratvars; retain _stratno 0; * assign a stratum number; if %makelist(&stratvars,first.,%str( or )) 0 then _stratno = _stratno + 1; label _stratno='_stratno: stratum id number'; run; * collapse over same value of covariate in same stratum * and add analytic _cases and _pt variables; proc sort data=_temp2; by _stratno &vlist; run; data _temp3; set _temp2; by _stratno &vlist; retain _casest _ptt; * initialize case and person-time counts; if %makelist(&vlist,first.,%str( or )) first._stratno then do; _casest = 0; _ptt = 0; end; * add in cases and person time; _casest = _casest + &cases ; _ptt = _ptt + &pt; * output after last record unless there is no person time for this value of the covariate; if (%makelist(&vlist,last.,%str( or )) last._stratno) and _ptt gt 0 then output; else delete; run; * get maximum number of unique covariate values within any stratum * and put it in a macro variable; proc freq data=_temp3; table _stratno /noprint out=_ncovals (rename=(count=_ncovals) drop=percent); run; proc sql noprint; select max(_ncovals) into :maxsetsize from _ncovals; quit; * get rid of leading blank; %let maxsetsize= &maxsetsize; %* size of array to hold covariate values; %let arraysize=%eval(&nvars*&maxsetsize); data &outdsn (keep= _stratno &stratvars _ncovals _totcases _totpt _z1_z&arraysize _cases1-_cases&maxsetsize _pt1-_pt&maxsetsize label="input data set: &indsn_pois, strata vars: &stratvars, variable list: &vlist, maximum unique covariates: &maxsetsize"); merge _ncovals _temp3; by _stratno; 2 retain _totcases _totpt; array vars{&nvars} &vlist; array _z{&nvars,&maxsetsize} ; array _cases{&maxsetsize}; array _pt{&maxsetsize}; retain _i _z1-_z&arraysize _cases1-_cases&maxsetsize _pt1-_pt&maxsetsize; * initialize covariate, case, and person time arrays to missing; if first._stratno then do; _i = 0; do _ii=1 to &maxsetsize; do _ivar = 1 to &nvars; _z(_ivar,_ii)=.; end; _cases(_ii)=.; _pt(_ii) = .; end; _totcases = 0; _totpt = 0; end; * put unique covariate values for each stratum into z array; _i = _i + 1; * loop through all variables; do _ivar = 1 to &nvars; _z{_ivar,_i} = vars{_ivar}; end; _cases(_i)=_casest; _pt(_i) =_ptt; _totcases = _totcases + _casest; _totpt = _totpt + _ptt; * when through the stratum information is output; * only retain strata with non zero cases and person time as these * are the only ones that contribute to the estimation; if last._stratno and _totcases gt 0 and _totpt gt 0 then output; label _totcases='_totcases: total number of cases in stratum'; label _totpt='_totpt: total person time for the stratum'; label _ncovals='_ncovals: number of unique covariate values'; run; * clean up; proc datasets; delete _ncovals _temp1 _temp2 _temp3; quit; %put input data set: &indsn_pois; %put strata variables: &stratvars; %put analysis variable list: &vlist; %put maximum unique covariate values _ncovals: &maxsetsize; %put output data set: &outdsn; %put Above information is in the output data set label; %mend; 3