%macro eststats (version, data=_last_ , /* Input data set. Default is last created */ /* data set. */ out=eststats, /* Name of output data set containing the */ /* tests and confidence bounds. */ /*REQUIRED*/ method= , /* METHOD=REG for normal regression, */ /* METHOD=LOGISTIC for logistic model, */ /* METHOD=PROBIT for probit model, */ /* METHOD=PHREG for proportional hazards model*/ /* METHOD=LIFEREG for accelerated failure time*/ /* model. */ /*REQUIRED*/ y= , /* Dependent variable - this may be a single */ /* variable name or events/trials form for */ /* logistic and probit models or (time1,time2)*/ /* form for counting process input in */ /* proportional hazards models and interval */ /* censoring in accelerated failure time */ /* time models. */ x= , /* Independent variable(s). Must NOT be a */ /* list e.g. var1-var10. If not specified, */ /* a model containing only an intercept is */ /* fit. Separate variable names by blanks, */ /* not commas. */ by= , /* Variables defining BY groups. Must NOT */ /* be a list e.g. var1-var10. */ freq= , /* Frequency variable (used in FREQ statement)*/ /* This should not be specified for LIFEREG */ /* models. */ weight= , /* Weight variable (used in WEIGHT statement) */ /* This should not be specified for PHREG */ /* models. */ censor= , /* Censoring variable and values for PHREG */ /* models. Example: censor=status(0) */ dist= , /* Distribution for LIFEREG models. Specify */ /* as shown in LIFEREG documentation. */ descend= , /* DESCENDING option for logistic and probit */ /* models. See LOGISTIC documentation. */ /* Specify descend=des to use the DESCENDING */ /* option. */ order=formatted , /* ORDER= option for logistic and probit */ /* models. See LOGISTIC documentation. */ nolog= , /* NOLOG option for LIFEREG models. See */ /* LIFEREG documentation. Specify nolog=nolog*/ /* to use the NOLOG option. */ ties=breslow, /* TIES= option for PHREG models. Specify as */ /* shown in PHREG documentation. */ alpha=.05 , /* Alpha level for confidence bounds. Value */ /* must be between 0 and 1. alpha=.05 yields */ /* 95% confidence bounds. */ print=no , /* Show regression procedure output? (yes, no)*/ form=statrow /* Output data set has statistics as rows, */ /* variables as columns (OUTEST= form). If */ /* outform=statcol, then statistics are */ /* columns, variables are rows. */ ); %if &version ne %then %put ESTSTATS macro Version 2.4; %if %substr(&sysvlong,1,1)>=7 %then %do; %put ESTSTATS: This macro is obsolete. Use the global ODS OUTPUT statement; %put %str( to output the tables you need. Use the ODS TRACE); %put %str( statement or see the procedure documentation to find the); %put %str( table names. Aborting.); %goto abrt; %end; options nonotes nostimer; /* SOME LIMITED ERROR CHECKING */ /* Verify that Y= option is specified */ %if %quote(&y)= %then %do; %put ERROR: Specify dependent variable in the Y= argument; %goto exit; %end; /* Verify that METHOD= option is specified and is correct */ %if %upcase(&method) ne REG and %upcase(&method) ne LOGISTIC and %upcase(&method) ne PROBIT and %upcase(&method) ne LIFEREG and %upcase(&method) ne PHREG %then %do; %put ERROR: METHOD= must be REG, LOGISTIC, PROBIT, PHREG, or LIFEREG; %goto exit; %end; /* Get number of regressors */ %let i=1; %do %while (%scan(&x,&i) ne %str() ); %let arg&i=%scan(&x,&i); %let i=%eval(&i+1); %end; %let nx=%eval(&i-1); /* Sort the data by the BY variables if BY variables are given */ %if &by ne %then %do; proc sort data=&data out=_regin_; by &by; run; %end; /* MODEL FITTING -- Output parameter estimates & covariance matrix with OUTEST= for each BY group. */ %let proc=&method; %if %upcase(&method)=PROBIT %then %let proc=logistic; proc &proc data=%if &by ne %then _regin_; %else &data; outest=_est_ covout %if %upcase(&method)=REG %then outsscp=_sscp_; %if %upcase(&method)=LOGISTIC or %upcase(&method)=PROBIT %then %do; %if %upcase(&descend)=DES %then descending; %if &order ne %then order=ℴ %end; %if %upcase(&print)=NO %then noprint; ; model %quote(&y) %if (%upcase(&method)=PHREG or %upcase(&method)=LIFEREG) and %quote(&censor) ne %then *&censor; = &x / %if %upcase(&method)=PROBIT %then %do; link=probit technique=newton %end; %if %upcase(&method)=LIFEREG and &dist ne %then dist=&dist; %if %upcase(&method)=PHREG and &ties ne %then ties=&ties; %if %upcase(&method)=LIFEREG and %upcase(&nolog)=NOLOG %then nolog; ; %if &by ne %then %str(by &by;); %if &freq ne %then %str(freq &freq;); %if &weight ne %then %str(weight &weight;); run; %let dsid=%sysfunc(open(_est_)); %if &dsid %then %do; %let v6intcep=%sysfunc(varnum(&dsid,INTERCEP)); %let v6intcpt=%sysfunc(varnum(&dsid,INTERCPT)); %let rc=%sysfunc(close(&dsid)); %end; %else %do; %put ERROR: Could not open OUTEST= data set.; %goto exit; %end; /* Convert covariance matrix to one observation of standard errors. Add sample size in REG models. */ %let int=1; %let sclshp=0; %if &v6intcep > 0 %then %let arrvars=intercep &x; %else %if &v6intcpt > 0 %then %let arrvars=intercpt &x; %else %let arrvars=Intercept &x; %if %upcase(&method)=PHREG %then %do; %let int=0; %let arrvars=&x; %end; %if %upcase(&method)=LIFEREG %then %do; %let sclshp=1; %if &v6intcep > 0 %then %let arrvars=intercep &x _scale_; %else %if &v6intcpt > 0 %then %let arrvars=intercpt &x _scale_; %else %let arrvars=Intercept &x _scale_; %if %upcase(&dist)=GAMMA %then %do; %let sclshp=2; %if &v6intcep > 0 %then %let arrvars=intercep &x _scale_ _shape1_; %else %if &v6intcpt > 0 %then %let arrvars=intercpt &x _scale_ _shape1_; %else %let arrvars=Intercept &x _scale_ _shape1_; %end; %end; data _estse_; array _x{%eval(&nx+&int+&sclshp)} &arrvars; array se{%eval(&nx+&int+&sclshp)}; keep _type_ &by &arrvars; /* Pick out stderrs */ do i=1 to &nx+1+&int+&sclshp; set _est_; if _type_='PARMS' then output; else se{i-1}=sqrt(_x{i-1}); end; /* Add observation of stderrs */ _type_='STDERR'; do i=1 to &nx+&int+&sclshp; _x{i}=se{i}; end; output; /* Add observation of sample sizes in REG models */ %if %upcase(&method)=REG %then %do; set _sscp_ (where=(_type_='N')); output; run; %end; /* Make each estimate a row. Columns for each statistic. */ proc transpose data=_estse_ out=_testse_ (rename=(col1=parms col2=stderr %if %upcase(&method)=REG %then col3=n; _name_=variable) ); %if &by ne %then %str(by &by;); var &arrvars; run; /* Compute test statistic, p-value and confidence bounds */ %if %upcase(&form)=STATCOL %then %str(options notes stimer;); %if %upcase(&method)=REG %then %do; data &out; set _testse_; t=parms/stderr; p=2*probt(-abs(t),n-&nx-1); tval=-tinv(&alpha/2,n-&nx-1); beta_lcl=parms-tval*stderr; beta_ucl=parms+tval*stderr; drop tval n; run; %end; %if %upcase(&method)=LOGISTIC or %upcase(&method)=PROBIT or %upcase(&method)=LIFEREG or %upcase(&method)=PHREG %then %do; data &out; set _testse_; if variable notin ('_SCALE_','_SHAPE1_') then do; chisq=(parms/stderr)**2; p=1-probchi(chisq,1); beta_lcl=parms-probit(1-(&alpha/2))*stderr; beta_ucl=parms+probit(1-(&alpha/2))*stderr; %if %upcase(&method)=LOGISTIC %then %do; if upcase(substr(variable,1,8)) notin ('INTERCEP','INTERCPT') then do; or=exp(parms); or_lcl=exp(beta_lcl); or_ucl=exp(beta_ucl); end; %end; %if %upcase(&method)=PHREG %then %do; rr=exp(parms); rr_lcl=exp(beta_lcl); rr_ucl=exp(beta_ucl); %end; end; run; %end; /* Put in OUTEST= form */ %if %upcase(&form)=STATROW %then %do; options notes stimer; proc transpose data=&out out=&out (rename=(_name_=_type_)); id variable; %if &by ne %then %str(by &by;); run; %end; %exit: options notes stimer; %abrt: %mend eststats;