%macro probcounts(version, data=, inmodel=, inzeromodel=, modeloffset=, zerooffset=, zerolink=logistic, counts=, pred=, proc=countreg, out=probcounts, prefix=Pr); %let _version=1.2; %if &version ne %then %put PROBCOUNTS macro Version &_version; %let opts = %sysfunc(getoption(notes)); %if &version ne debug %then %str(options nonotes;); /* Check for newer version */ %if %sysevalf(&sysver >= 8.2) %then %do; %let _notfound=0; filename _ver url 'http://ftp.sas.com/techsup/download/stat/versions.dat' termstr=crlf; data _null_; infile _ver end=_eof; input name:$15. ver; if upcase(name)="&sysmacroname" then do; call symput("_newver",ver); stop; end; if _eof then call symput("_notfound",1); run; %if &syserr ne 0 or &_notfound=1 %then %put &sysmacroname: Unable to check for newer version; %else %if %sysevalf(&_newver > &_version) %then %do; %put &sysmacroname: A newer version of the &sysmacroname macro is available.; %put %str( ) You can get the newer version at this location:; %put %str( ) http://support.sas.com/ctx/samples/index.jsp; %end; %end; /* Check for required options and data sets */ %if &data= or %sysfunc(exist(&data)) ne 1 %then %do; %put ERROR: DATA= data set not specified or not found.; %goto exit; %end; %if &inmodel= or %sysfunc(exist(&inmodel)) ne 1 %then %do; %put ERROR: INMODEL= data set not specified or not found; %put PROBCOUNTS: Use this statement in PROC COUNTREG to create an INMODEL= data set:; %put %str( )ods output ParameterEstimates = ; %goto exit; %end; %if &counts= and &pred= %then %do; %put ERROR: Either COUNTS= or PRED= must be specified.; %goto exit; %end; %if %upcase(%substr(&zerolink,1,1))=L or &zerolink= %then %let zerolink=L; %else %if %upcase(%substr(&zerolink,1,1))=N or %upcase(%substr(&zerolink,1,1))=P %then %let zerolink=N; %else %if %upcase(%substr(&zerolink,1,1))=C %then %let zerolink=C; %else %do; %put ERROR: If specified, ZEROLINK= must be LOGISTIC, NORMAL, or CLOGLOG.; %goto exit; %end; %if %upcase(%substr(&proc,1,1))=C or proc= %then %let proc=C; %else %if %upcase(%substr(&proc,1,1))=G %then %let proc=G; %else %do; %put ERROR: If specified, PROC= must be COUNTREG or GENMOD.; %goto exit; %end; %if &zerolink=C and &proc=C %then %do; %put ERROR: ZEROLINK=CLOGLOG only valid with PROC=GENMOD.; %goto exit; %end; %if &zerooffset ne and &proc=G %then %do; %put ERROR: ZEROOFFSET= not valid for analysis based on GENMOD results.; %goto exit; %end; %if &inzeromodel ne and &proc=C %then %do; %put ERROR: INZEROMODEL= not valid with PROC=COUNTREG.; %goto exit; %end; /* Arrange parameter estimates for use as SCORE= in PROC SCORE */ %let NBdisp=; %let zi=0; data _pe2; set &inmodel; %if &proc=G %then %do; if parameter="Dispersion" then do; %end; %else %do; if parameter="_Alpha" then do; %end; call symput("NBdisp",Estimate); delete; end; %if &proc=G %then %do; if parameter="Scale" then delete; %end; if index(parameter,'Restrict') ne 0 then delete; model='Mean'; if index(parameter,'Inf_') ne 0 then do; parameter=substr(parameter,5); model='Inf'; call symput("zi",1); end; run; %if &proc=G and &inzeromodel ne %then %do; data _pe2; set _pe2 &inzeromodel(in=inz); if inz then do; model='Inf'; call symput("zi",1); end; run; %end; proc transpose data=_pe2 out=_estparms; var estimate; by notsorted model; id parameter; run; data _estparms; set _estparms; _TYPE_="PARMS"; _NAME_=model; drop model; %if &modeloffset ne %then %str(if _name_='Mean' then &modeloffset=1;); %if &zerooffset ne %then %str(if _name_='Inf' then &zerooffset=1;); run; /* Add Intercept to data so VAR not needed in PROC SCORE */ data _datacopy; set &data; Intercept=1; run; /* Get scores for poisson process and zeros process */ proc score data=_datacopy score=_estparms out=_pred type=PARMS; run; %if &syserr ne 0 %then %goto exit; /* Compute predicted values and/or probabilities of specified counts */ data _pred; set _pred; _obs=_n_; do i= %if &pred ne %then %do; -1 %if &counts ne %then ,; %end; &counts; if Mean=. then _py=.; else do; if i=-1 then _py=exp(Mean); else _py= %if &NBdisp= %then pdf('poisson',i,exp(Mean)); %else pdf('negbinomial',i,1/(1+&NBdisp*exp(Mean)),1/&NBdisp); ; end; if Inf ne . then _p0= %if &zerolink=L %then logistic(Inf); %if &zerolink=N %then probnorm(Inf); %if &zerolink=C %then 1-exp(-exp(Inf)); ; else _p0=0; if (&zi=1 and Inf=.) or _py=. then _pcount=.; else _pcount=_py*(1-_p0)+(i=0)*_p0; output; end; run; /* Arrange probabilities, predicteds as columns and merge with input data */ proc transpose data=_pred prefix=&prefix out=&out(drop=_obs _name_ rename=(&prefix._1=&pred)); by _obs; var _pcount; id i; run; options notes; data &out; merge &data &out; run; %exit: options &opts; %mend;