options nosymbolgen nomprint nospool; /* The following example uses many of these features and is long and rather complicated. It shows examples of nested macros, DO loops, and many macro functions. */ ODS listing close; data a; input stress elev die; datalines; 70 150 1 80 175 1 50 125 1 60 130 1 40 200 1 65 144 1 75 170 1 80 90 1 70 200 1 60 175 1 65 225 0 50 100 0 45 125 0 35 150 0 40 175 0 50 140 0 55 180 0 45 130 0 50 200 0 60 150 0 ; /* This macro counts the number of words in a string, where words are separated by spaces as would be found in a list of variables. */ %MACRO wordcount(string); %LOCAL count word; %LET count=1; %LET word=%SCAN(&string,&count,%STR( )); %DO %WHILE(&word ne); %LET count=%EVAL(&count+1); %LET word=%SCAN(&string,&count,%STR( )); %END; %EVAL(&count-1) %MEND wordcount; /* This macro generates a series of macro variable names of the form var1 ... varn. You pass into the macro how many names you want to create and what you want the prefix to be, e.g. v1 to vn. */ %MACRO mnames(number, prefix=v); %LOCAL i; %DO i = 1 %TO &number; &prefix&i %END; %MEND mnames; /* This macro breaks apart a string into its component words and counts them. It calls the "wordcount" and "mnames" macros above. It takes the string that has all the independent variables listed, calls "mnames" to create the macro variables names, then assigns to them the names of the actual independent variables. The value of ivar1 is the name of the first independent variable, the value of ivar2 is the name of the second indepedent variable, etc.. */ %MACRO gvars(string, vname=ivar); %LOCAL j; %GLOBAL params; %LET params = %wordcount(&string); %GLOBAL %mnames(¶ms, prefix=&vname); %DO j = 1 %TO ¶ms; %LET &vname&j = %SCAN(&string,&j,%STR( )); %END; %MEND gvars; %MACRO AICfits (dvar= , ivars= , link= ); %gvars(&ivars) ods output FitStatistics = AIC ParameterEstimates = ParamEst; proc logistic data=data&rep; model &dvar = &ivars / link = &link; title "&dvar - &ivars - &link"; run; data aic2; set aic; trial = &rep; if criterion ne "AIC" then delete; run; data ParamEst0; set ParamEst; if variable = "Intercept"; rename Estimate = InterceptEst StdErr = InterceptStderr WaldChiSq = InterceptWald ProbChiSq = InterceptP; drop variable; run; %DO k = 1 %TO ¶ms; %LET prefix = &&ivar&k; %LET est = %UNQUOTE(&prefix.Est); %LET std = %UNQUOTE(&prefix.Stderr); %LET wald = %UNQUOTE(&prefix.Wald); %LET prob = %UNQUOTE(&prefix.P); data ParamEst&k; set ParamEst; k = ¶ms+1; if variable = "&&ivar&k"; rename Estimate=&est; rename StdErr=&std; rename WaldChiSq=&wald; rename ProbChiSq=&prob; drop variable; run; %END; %* generates the names of the data files created above so you can merge them together; data ModelResults; merge aic2 paramest0 %DO k = 1 %TO ¶ms; paramest&k %END; ; run; proc append base=CompiledResults data=ModelResults force; run; %MEND AICfits; /* Macro to perform bootstrapping. Calls the AICfits macro. */ %MACRO BOOTREP; %GLOBAL rep; %DO rep = 1 %TO 10; proc surveyselect data = a outhits method = urs sampsize = 20 out=data&rep; run; %AICfits (dvar=die, ivars=stress elev, link=logit) %AICfits (dvar=die, ivars=stress elev, link=probit) %AICfits (dvar=die, ivars=stress elev, link=cloglog) %AICfits (dvar=die, ivars=stress, link=logit) %AICfits (dvar=die, ivars=stress, link=probit) %AICfits (dvar=die, ivars=stress, link=cloglog) %END; %MEND BOOTREP; %BOOTREP