*! version 1.0.0 31oct2006 program gpoisson, byable(onecall) prop(irr ml_score svyb svyj svyr swml) if _by() { local BY `"by `_byvars'`_byrc0':"' } `BY' _vce_parserun gpoisson : `0' if "`s(exit)'" != "" { exit } version 6, missing local version : di "version " string(_caller()) ":" if replay() { if "`e(cmd)'" != "gpoisson" { error 301 } if _by() { error 190 } global S_1 = e(chi2_c) Display `0' error `e(rc)' exit } `version' `BY' Estimate `0' end program Estimate, eclass byable(recall) /* Parse. */ version 6, missing local awopt = cond(_caller()<7, "aw", "") syntax varlist(numeric ts) [fw `awopt' pw iw] [if] [in] [, IRr /* */ FROM(string) Level(cilevel) OFFset(varname numeric ts) /* */ Exposure(varname numeric ts) noCONstant Robust CLuster(varname) /* */ SCore(string) noLOg noDISPLAY noLRtest /* */ CRITTYPE(passthru) * ] if _by() { _byoptnotallowed score() `"`score'"' } mlopts mlopts, `options' local cns `s(constraints)' local mlopts `mlopts' `crittype' local prog "gpois_lf" local parm "delta" local LLprog "LLalpha" local title "Generalized Poisson regression" /* Check syntax. */ if `"`score'"'!="" { local nword : word count `score' if `nword'==1 & substr("`score'",-1,1)=="*" { local score = /* */ substr("`score'",1,length("`score'")-1) local score `score'1 `score'2 local nword 2 } confirm new variable `score' if `nword' != 2 { di as err "score() must contain the name of " /* */ "two new variables" exit 198 } local scname1 : word 1 of `score' local scname2 : word 2 of `score' tempvar scvar1 scvar2 local scopt "score(`scvar1' `scvar2')" } if "`offset'"!="" & "`exposur'"!="" { di as err "only one of offset() or exposure() can be specified" exit 198 } if "`constan'"!="" { local nvar : word count `varlist' if `nvar' == 1 { di as err "independent variables required with " /* */ "noconstant option" exit 102 } } /* Mark sample except for offset/exposure. */ marksample touse if `"`cluster'"'!="" { markout `touse' `cluster', strok local clopt cluster(`cluster') local robust robust } if `"`weight'"' == "pweight" { local robust robust } /* Process offset/exposure. */ if "`exposur'"!="" { capture assert `exposur' > 0 if `touse' if _rc { di as err "exposure() must be greater than zero" exit 459 } tempvar offset qui gen double `offset' = ln(`exposur') local offvar "ln(`exposur')" } if "`offset'"!="" { markout `touse' `offset' local offopt "offset(`offset')" if "`offvar'"=="" { local offvar "`offset'" } } /* Count obs and check for negative values of `y'. */ gettoken y xvars : varlist tsunab y : `y' local yname : subinstr local y "." "_" if "`weight'"!="" { if "`weight'"=="fweight" { local wt `"[fw`exp']"' } else local wt `"[aw`exp']"' } summarize `y' `wt' if `touse', meanonly if r(N) == 0 { error 2000 } if r(N) == 1 { error 2001 } if r(min) < 0 { di as err "`y' must be greater than or equal to zero" exit 459 } if r(min) == r(max) & r(min) == 0 { di as err "`y' is zero for all observations" exit 498 } tempname mean scalar `mean' = r(mean) /* Check whether `y' is integer-valued. */ if "`display'"=="" { capture assert `y' == int(`y') if `touse' if _rc { di in gr "note: you are responsible for " /* */ "interpretation of non-count dep. variable" } } /* Print out aweight message. */ if "`display'"=="" & "`weight'"=="aweight" { di in gr "note: you are responsible for interpretation " /* */ "of analytic weights" } /* Remove collinearity. */ if "`display'"!="" & "`weight'"=="aweight" { _rmcoll `xvars' [iw`exp'] if `touse', `constan' /* aweights produce "sum of wgt" message, which is not wanted for -nodisplay- */ } else _rmcoll `xvars' [`weight'`exp'] if `touse', `constan' local xvars `r(varlist)' /* Run comparison Poisson model. */ if "`log'"!="" | "`display'"!="" { local nohead "*" } local poislf = . if `"`from'"'=="" & "`lrtest'"=="" { if "`robust'`cns'`cluster'"!="" | "`weight'"=="pweight" { local lrtest "nolrtest" } `nohead' di in gr _n "Fitting Poisson model:" poisson `y' `xvars' [`weight'`exp'] if `touse', /* */ nodisplay `offopt' `constan' `log' `mlopts' `robust' local poislf = e(ll) tempname bp mat `bp' = e(b) if "`lrtest'"=="" { tempname llp scalar `llp' = e(ll) } } else if `"`from'"'=="" { /* nolrtest */ capture poisson `y' `xvars' [`weight'`exp'] if `touse', /* */ `offopt' `constan' iter(1) capture local poislf = e(ll) tempname bp mat `bp' = e(b) } /* Fit constant-only model. */ if "`constan'"=="" & `"`from'"'=="" { /* Get starting values for constant-only model. */ if "`offset'"!="" { SolveC `y' `offset' [`weight'`exp'] if `touse', /* */ mean(`mean') local c = r(_cons) } else local c = ln(`mean') tempname b0 ll0 if `c' != . { mat `b0' = (`c', 0.0) } else mat `b0' = (0, 0.0) mat colnames `b0' = `y':_cons tanh`parm':_cons if "`weight'"=="aweight" { local wt `"[aw`exp']"' } else if "`weight'"!="" { local wt `"[iw`exp']"' } `nohead' di in gr _n "Fitting constant-only model:" version 8.1: /// ml model d2 `prog' (`yname': `y'=, `constan' `offopt') /* */ /tanh`parm' if `touse' `wt', /* */ collinear missing max nooutput nopreserve wald(0) /* */ init(`b0', copy) search(off) `mlopts' `log' `robust' /* */ nocnsnotes mat `b0' = e(b) scalar `ll0' = e(ll) local continu "continue" } /* Get starting values for full model. */ if `"`from'"'=="" { tempname pbp Zdp mat `Zdp' = (0.0) mat colnames `Zdp' = tanh`parm':_cons mat `pbp' = (`bp', `Zdp') if "`constan'"=="" { local dim = colsof(`bp') if `dim' > 1 { /* Adjust so that mean(x*b) = c0 from constant-only. */ tempvar xb qui mat score `xb' = `bp' if `touse' if "`weight'"!="" { local wt `"[aw`exp']"' } summarize `xb' `wt' if `touse', meanonly if "`offset'"!="" { qui replace `xb' = `xb' + `b0'[1,1] - r(mean) + `offset' } else { qui replace `xb' = `xb' + `b0'[1,1] - r(mean) } mat `bp'[1,`dim'] = `bp'[1,`dim'] + `b0'[1,1] /* */ - r(mean) /* Compute log likelihood and compare with constant-only model. */ mat `bp' = (`bp', `b0'[1,2..2]) `LLprog' `y' `xb' `b0'[1,2] [`weight'`exp'] /* */ if `touse', nobs(`r(N)') if r(lnf) > `ll0' & r(lnf)<. { if r(lnf) > `poislf' { local initopt "init(`bp')" } if `poislf' != . { local initopt "init(`pbp')" } } } if "`initopt'"=="" { local initopt "init(`b0')" if `poislf' != . & `poislf' > `ll0' & `dim' > 1 { local initopt "init(`pbp')" } } } else { tempname b0 mat `b0' = (0.0) mat colnames `b0' = tanh`parm':_cons mat `bp' = (`bp',`b0') local initopt "init(`bp')" } `nohead' di in gr _n "Fitting full model:" } else local initopt `"init(`from')"' /* Fit full model. */ version 8.1: /// ml model d2 `prog' (`yname': `y'=`xvars', `constan' `offopt') /* */ /tanh`parm' if `touse' [`weight'`exp'], collinear missing max /* */ nooutput nopreserve `initopt' search(off) `mlopts' `log' /* */ `scopt' `robust' `clopt' `continu' /* */ title(`title') /* */ diparm(tanh`parm', tanh label("`parm'")) est local cmd if "`score'"!="" { label var `scvar1' "Score index for x*b from poisson" rename `scvar1' `scname1' label var `scvar2' /* */ "Score index for /tanh`parm' from poisson" rename `scvar2' `scname2' est local scorevars `scname1' `scname2' } if "`llp'"!="" { est local chi2_ct "LR" est scalar ll_c = `llp' if (e(ll) < e(ll_c)) | (_b[/tanh`parm'] < -20) { est scalar chi2_c = -12.0 /* otherwise, let it be negative when it does not converge */ } else est scalar chi2_c = 2*(e(ll)-e(ll_c)) } if "`cluster'"=="" & "`weight'"!="pweight" { est scalar r2_p = 1 - e(ll)/e(ll_0) } tempname tmpparm scalar `tmpparm' = exp(2*_b[/tanh`parm']) est scalar k_aux = 1 est local diparm_opt2 noprob est scalar `parm' = (`tmpparm'-1)/(`tmpparm'+1) est scalar dispersion = (`tmpparm'+1)/2.0 est local offset "`offvar'" est local offset1 /* erase; set by -ml- */ est local predict "gpois_p" est local cmd "gpoisson" /* Double save. */ global S_E_ll = e(ll) global S_E_ll0 `e(ll_0)' global S_E_llc `e(ll_c)' global S_1 `e(chi2_c)' global S_E_chi2 = e(chi2) global S_E_mdf = e(df_m) global S_E_pr2 `e(r2_p)' global S_E_nobs = e(N) global S_E_tdf = e(N) global S_E_off `e(offset)' global S_E_depv `e(depvar)' global S_E_cmd `e(cmd)' if "`display'"=="" { Display, `irr' level(`level') } error `e(rc)' end program Dihead di in gr _n "`e(title)'" _col(51) "Number of obs =" /* */ in ye _col(70) %9.0g e(N) local crtypel = substr("`e(crittype)'", 1, 1) local crtyper = substr("`e(crittype)'", 2, .) local crtypel = upper("`crtypel'") local crtype "`crtypel'`crtyper'" local col = length("`crtype'") + 2 if ("`e(chi2type)'"== "Wald") { di in gr "" _col(51) /* */ as txt "`e(chi2type)' chi2(" as res e(df_m) in gr ")" /* */ _col(67) "=" in ye _col(70) %9.2f e(chi2) di as txt "Prob > chi2" _col(67) "=" /* */ in ye _col(70) %9.4f e(p) di as txt "Dispersion" _col(16) "= " as res %9.0g e(dispersion) /* */ _col(51) in gr "Prob > chi2" _col(67) "=" in ye _col(70) %9.4f e(p) di in gr "`crtype'" _col(16) "= " as res e(ll) /* */ in gr _col(51) "Pseudo R2" _col(67) "=" in ye _col(70) %9.4f e(r2_p) _n } else if ("`e(chi2type)'"== "LR") { di in gr _col(51) /* */"`e(chi2type)' chi2(" as res e(df_m) in gr ")" _col(67) "="/* */ in ye _col(70) %9.2f e(chi2) di as txt "Dispersion" _col(16) "= " as res %9.0g e(dispersion) /* */ _col(51) in gr "Prob > chi2" _col(67) "=" in ye _col(70) %9.4f e(p) di in gr "`crtype'" _col(16) "= " as res e(ll) /* */ in gr _col(51) "Pseudo R2" _col(67) "=" in ye _col(70) %9.4f e(r2_p) _n } else { exit } end program Display syntax [, Level(cilevel) IRr] if "`irr'"!="" { local eopt "eform(IRR)" } local parm "delta" Dihead version 9: ml di, level(`level') `eopt' nohead nofootnote if "`e(chi2_ct)'"!="LR" { exit } if ((e(chi2_c) > 0.005) & (e(chi2_c)<1e4)) | (ln(e(`parm')) < -20) { local fmt "%8.2f" } else local fmt "%8.2e" tempname pval scalar `pval' = chiprob(1, e(chi2_c))*0.5 if ln(e(`parm')) < -20 { scalar `pval'= 1 } di in smcl as txt "Likelihood-ratio test of `parm'=0: " /* */ as txt "{help j_chibar##|_new:chibar2(1) =}" as res `fmt' /* */ e(chi2_c) as txt " Prob>=chibar2 = " as res %6.4f /* */ `pval' _prefix_footnote end program SolveC, rclass /* modified from poisson.ado */ gettoken y 0 : 0 gettoken xb 0 : 0 syntax [fw aw pw iw] [if] , Mean(string) if "`weight'"=="pweight" | "`weight'"=="iweight" { local weight "aweight" } summarize `xb' `if', meanonly if r(max) - r(min) > 2*709 { /* unavoidable exp() over/underflow */ exit /* r(_cons) >= . */ } if r(max) > 709 | r(min) < -709 { tempname shift if r(max) > 709 { scalar `shift' = 709 - r(max) } else scalar `shift' = -709 - r(min) local shift "+`shift'" } tempvar expoff qui gen double `expoff' = exp(`xb'`shift') `if' summarize `expoff' [`weight'`exp'], meanonly return scalar _cons = ln(`mean')-ln(r(mean))`shift' end program LLalpha, rclass gettoken y 0 : 0 gettoken z 0 : 0 gettoken b0 0 : 0 syntax [fw aw pw iw] [if], Nobs(string) if "`weight'"!="" { if "`weight'"=="fweight" { local wt `"[fw`exp']"' } else local wt `"[aw`exp']"' } tempname del scalar `del' = exp(2*`b0')/(1+exp(2*`b0')) tempname maxdel scalar `maxdel' = 0.99999999 if `b0' > 300 | `del' > `maxdel' { scalar `del' = `maxdel' } tempname onemd scalar `onemd' = 1.0 - `del' tempvar mu den qui gen double `mu' = exp(`z') `if' qui gen double `den'= `onemd'*`mu'+`del'*`y' `if' qui replace `z' = -`onemd'*`mu' - `del'*`y' + /* */ (`y'-1)*log(`den') + `z' + log(`onemd') - lngamma(`y'+1) summarize `z' `wt' `if', meanonly if r(N) != `nobs' { exit } if "`weight'"=="aweight" { ret scalar lnf = r(N)*r(mean) /* weights not normalized in r(sum) */ } else ret scalar lnf = r(sum) end exit Notes: Model Starting values ------------- ------------------------- gpoisson, cons best of 1. b0 = (c0, lnparm0) constant-only estimates 2. (bp=poisson coefficients, c, lnparm0), where c is such that mean(bp + c + offset) = mean(c0 + offset); i.e., adjusted to constant- only value 3. (bp=poisson coefficients, poisson constant, -12) gpoisson, nocons (bp=poisson, 0)