📄 xtnbreg.ado
字号:
*! version 1.7.21 21jun2005
program define xtnbreg, byable(onecall) prop(irr)
local vv : display "version " string(_caller()) ", missing:"
version 6, missing
if replay() {
if "`e(cmd)'"!="xtnbreg" & "`e(cmd2)'"!="xtnbreg" {
error 301
}
if _by() { error 190 }
if "`e(cmd)'" == "xtgee" {
syntax [, IRr EForm ]
if "`irr'"!="" {
local eform "eform"
}
xtgee , `eform'
exit
}
Display `0'
error `e(rc)'
exit
}
if _by() {
local by "by `_byvars'`_byrc0':"
}
`vv' `by' _vce_parserun xtnbreg, panel : `0'
if "`s(exit)'" != "" {
exit
}
nobreak {
capture noisily break {
`by' Estimate `0'
}
macro drop S_XT*
exit _rc
}
end
program define Estimate, eclass byable(recall) sort
qui q born
local afwgt = cond($S_1<14679, "aweight", "fweight")
syntax varlist(numeric ts) [if] [in] [iweight `afwgt' pweight] /*
*/ [, I(varname num) RE FE PA IRr EForm noCONstant noSKIP /*
*/ noDIFficult EXPosure(varname num) OFFset(varname num) /*
*/ FROM(string) Level(cilevel) noLOg * ]
if length("`fe'`re'`pa'") > 2 {
di in red "choose one of re, fe, or pa"
exit 198
}
/* Mark sample except for offset/exposure. */
marksample touse
xt_iis `i'
local ivar "`s(ivar)'"
markout `touse' `ivar' /* iis does not allow string */
if "`pa'"!="" {
if "`i'"!="" { local iarg "i(`i')" }
if "`offset'"!="" {
local offset "offset(`offset')"
}
if "`exposur'"!="" {
local exposur "exposure(`exposur')"
}
if `"`from'"' != "" {
local farg "from(`from')"
}
if "`irr'"!="" {
local eform "eform"
}
xtgee `varlist' if `touse' [`weight'`exp'], /*
*/ fam(nbinom) link(log) rc0 level(`level') /*
*/ `farg' `iarg' `constan' `offset' `exposur' /*
*/ `eform' `log' `options'
est local predict xtnbreg_pa_p
if e(rc) == 0 | e(rc) == 430 {
est local estat_cmd "" // reset from xtgee
est local cmd2 "xtnbreg"
}
error `e(rc)'
exit
}
/* If here, we are doing re (default) or fe. */
if "`fe'`re'"=="" { local re "re" }
mlopts mlopts, `options'
local difficu = cond("`difficu'"=="", "difficult", "")
if "`weight'"!="" & "`weight'"!="iweight" {
noi di in red /*
*/ "`weight' not allowed with fixed- and random-effects models"
exit 101
}
if "`offset'"!="" & "`exposur'"!="" {
di in red "only one of offset() or exposure() can be specified"
exit 198
}
if "`constan'"!="" {
local nvar : word count `varlist'"
if `nvar' == 1 {
di in red "independent variables required with " /*
*/ "noconstant option"
exit 102
}
}
if "`fe'"!="" {
local title "Conditional FE negative binomial regression"
local prog "xtnb_fe"
}
else {
local title "Random-effects negative binomial regression"
local prog "xtnb_lf"
local distr "Beta"
local eqaux "/ln_r /ln_s"
}
/* Process offset/exposure. */
if "`exposur'"!="" {
capture assert `exposur' > 0 if `touse'
if _rc {
di in red "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'"
}
}
if "`skip'"=="" | `"`from'"'!="" | "`constan'"!="" {
local skip "skip"
}
else local skip
/* Count obs, check for negative values of `y', and compute mean. */
gettoken y xvars : varlist
local yname `y'
local ystr : subinstr local yname "." "_"
local xvarsnm `xvars'
_find_tsops `y' `xvars'
if `r(tsops)' {
qui tsset
tsrevar `y'
local y `r(varlist)'
tsrevar `xvars'
local xvars `r(varlist)'
}
summarize `y' if `touse', meanonly
if r(N) == 0 { error 2000 }
if r(N) == 1 { error 2001 }
if r(min) < 0 {
di in red "`y' must be greater than or equal to zero"
exit 459
}
tempname mean
scalar `mean' = r(mean)
/* Issue warning if `y' is not an integer. */
capture assert `y' == int(`y') if `touse'
if _rc {
di in gr "note: you are responsible for " /*
*/ "interpretation of non-count dep. variable"
}
/* Sort. */
tempvar nn
gen long `nn' = _n
sort `touse' `ivar' `nn' /* deterministic sort */
/* Check weights. */
if "`weight'"!="" {
tempvar w
qui gen double `w' `exp'
_crcchkw `ivar' `w' `touse'
drop `w'
}
/* For fe model, drop any groups with `y' all zeros or those of size 1. */
if "`fe'"!="" {
DropOne `touse' `ivar' `nn' `y' `mean'
DropZero `touse' `ivar' `nn' `y' `mean'
}
drop `nn'
/* Remove collinearity. */
local oldxvars `xvars'
qui _rmcoll `xvars' [`weight'`exp'] if `touse', `constan'
local xvars "`r(varlist)'"
local dropped : list oldxvars - xvars
foreach x of local dropped {
local j : list posof "`x'" in oldxvars
local x2 : word `j' of `xvarsnm'
noi di as txt "note: `x2' dropped due to collinearity"
}
/* Set up global for use by likelihood program. */
global S_XTby "`touse' `ivar'"
quietly {
tempvar nn
gen long `nn' = _n
sort `touse' `ivar' `nn' /* deterministic sort */
drop `nn'
/* Check weights. */
if "`weight'"!="" {
tempvar w
gen double `w' `exp'
_crcchkw `ivar' `w' `touse'
drop `w'
}
/* Get number of groups and group size min, mean, and max. */
tempvar T
by `touse' `ivar': gen long `T' = _N if _n==1 & `touse'
summarize `T' if `touse', meanonly
local ng = r(N)
local g1 = r(min)
local g2 = r(mean)
local g3 = r(max)
}
if "`log'"!="" { local qui "quietly" }
/* Get comparison/starting values:
nbreg, disp(con) for re model
poisson, iter(1) for fe model
*/
if `"`from'"'=="" {
if "`re'"!="" {
`qui' di in gr _n "Fitting negative " /*
*/ "binomial (constant dispersion) model:"
`qui' nbreg `y' `xvars' if `touse' [`weight'`exp'], /*
*/ `constan' `offopt' `mlopts' nodisplay disp(con)
tempname llp b0
scalar `llp' = e(ll)
mat `b0' = e(b)
local init0 "init(`b0',skip)"
}
else {
capture poisson `y' `xvars' if `touse' /*
*/ [`weight'`exp'], `constan' `offopt' iter(1)
if _rc == 0 {
tempname b0
mat `b0' = e(b)
local init0 "init(`b0')"
}
}
local b0n : colfullnames `b0'
local b0n : subinstr local b0n "`y'" "`ystr'", all
mat colnames `b0' = `b0n'
}
else local init0 `"init(`from')"'
/* Fit constant-only model. */
if "`skip'"=="" {
/* 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')
if `c'>=. { local c 0 }
tempname b00
if "`re'"!="" {
mat `b00' = (`c', 0, 0)
mat colnames `b00' = `y':_cons ln_r:_cons ln_s:_cons
}
else {
mat `b00' = (`c')
mat colnames `b00' = `y':_cons
}
`qui' di _n in gr "Fitting constant-only model:"
ml model d2 `prog' (`ystr': `y' = , `offopt') `eqaux' /*
*/ if `touse' [`weight'`exp'], /*
*/ collinear missing max nooutput nopreserve wald(0) /*
*/ init(`b00') search(off) `mlopts' `log' `difficu'
if "`xvars'"=="" { local init0 /* erase macro */ }
local continu "continue"
`qui' di in gr _n "Fitting full model:"
}
else if `"`from'"'=="" & "`re'"!="" {
`qui' di in gr _n "Fitting full model:"
}
/* Fit full model. */
ml model d2 `prog' (`ystr': `y' = `xvars', `constan' `offopt') `eqaux'/*
*/ if `touse' [`weight'`exp'], /*
*/ collinear missing max nooutput nopreserve `init0' search(off) /*
*/ `mlopts' `log' `difficu' `continu' title(`title')
est local cmd
/* Redo matrix stripes on b and V, removing names of tempvars due to TS ops */
tempname b V
matrix `b' = e(b)
matrix `V' = e(V)
local names : colfullnames `b'
foreach x of local xvars {
local j : list posof "`x'" in oldxvars
local x2 : word `j' of `xvarsnm'
local names : subinstr local names "`x'" "`x2'"
}
mat colnames `b' = `names'
mat colnames `V' = `names'
mat rownames `V' = `names'
est repost b = `b' V = `V', rename
if "`llp'"!="" {
est local chi2_ct "LR"
est scalar ll_c = `llp'
if e(ll) < e(ll_c) {
est scalar chi2_c = 0
}
else est scalar chi2_c = 2*(e(ll)-e(ll_c))
}
est local depvar "`yname'"
est scalar N_g = `ng'
est scalar g_min = `g1'
est scalar g_avg = `g2'
est scalar g_max = `g3'
if "`re'"!="" {
est scalar r = exp(_b[/ln_r])
est scalar s = exp(_b[/ln_s])
}
est local method "ml"
est local distrib "`distr'"
est local ivar "`ivar'"
est local offset1 /* erase from ml */
est local offset "`offvar'"
est local predict "xtnbreg_refe_p"
est local cmd2 "xtn_`re'`fe'"
est local cmd "xtnbreg"
Display , level(`level') `irr' `eform'
error `e(rc)'
end
program define Display
syntax [, Level(cilevel) IRr EForm ]
if "`eform'"!="" { local irr "irr" }
if "`irr'"!="" { local irr "eform(IRR)" }
_crcphdr
if "`e(cmd2)'"=="xtn_re" { local plus "plus" }
version 9: ///
ml mlout, level(`level') `irr' first nohead `plus' nofootnote
if "`e(cmd2)'"=="xtn_re" {
_diparm ln_r, level(`level') noprob
_diparm ln_s, level(`level') noprob
di in smcl in gr "{hline 13}{c +}{hline 64}"
_diparm ln_r, level(`level') exp label("r")
_diparm ln_s, level(`level') exp label("s")
di in smcl in gr "{hline 13}{c BT}{hline 64}"
if e(chi2_c)>=. { exit }
tempname pval
scalar `pval' = chiprob(1, e(chi2_c))*0.5
if e(chi2_c)==0 { scalar `pval'= 1 }
if ((e(chi2_c) > 0.005) & (e(chi2_c)<1e4)) | (e(chi2_c)==0) {
local fmt "%8.2f"
}
else local fmt "%8.2e"
di in green "Likelihood-ratio test vs. pooled: " _c
di in green in smcl "{help j_chibar##|_new:chibar2(01) = }" /*
*/ in ye `fmt' e(chi2_c) _c
di in green " Prob>=chibar2 = " in ye %5.3f /*
*/ `pval'
}
_prefix_footnote
end
program define DropOne /* drop groups of size one */
args touse ivar nn y mean
tempvar one
qui by `touse' `ivar': gen byte `one' = (_N==1) if `touse'
qui count if `one' & `touse'
local ndrop `r(N)'
if `ndrop' == 0 { exit } /* no groups with all zeros */
if `ndrop' > 1 { local s "s" }
di in gr "note: `ndrop' group`s' " /*
*/ "(`ndrop' obs) dropped because of only one obs per group"
qui replace `touse' = 0 if `one' & `touse'
sort `touse' `ivar' `nn' /* redo sort */
summarize `y' if `touse', meanonly
if r(N) == 0 { error 2000 }
if r(N) == 1 { error 2001 }
scalar `mean' = r(mean)
end
program define DropZero /* drop groups with all zero counts */
args touse ivar nn y mean
tempvar sumy
qui by `touse' `ivar': gen double `sumy' = /*
*/ cond(_n==_N, sum(`y'), .) if `touse'
qui count if `sumy'==0
local ngrp `r(N)'
if `ngrp' == 0 { exit } /* no groups with all zeros */
qui by `touse' `ivar': replace `sumy' = `sumy'[_N] if `touse'
qui count if `sumy'==0
local ndrop `r(N)'
if `ngrp' > 1 { local s "s" }
di in gr "note: `ngrp' group`s' " /*
*/ "(`ndrop' obs) dropped due to all zero outcomes"
qui replace `touse' = 0 if `sumy'==0 & `touse'
sort `touse' `ivar' `nn' /* redo sort */
summarize `y' if `touse', meanonly
if r(N) == 0 { error 2000 }
if r(N) == 1 { error 2001 }
scalar `mean' = r(mean)
end
program define 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
exit
Notes:
1. Uses -difficult- optimizer by default. Specify -nodifficult- to get
standard optimizer.
2. Skips the constant-only model by default. Specify -noskip- to estimate
constant-only model.
3. Model Starting values
-------------------------- ----------------
xtnbreg, fe (full model) poisson, iter(0)
xtnbreg, fe (constant only) ln(mean) or SolveC
xtnbreg, re (full model) nbreg, disp(con) and ln_r = ln_s = 0
xtnbreg, re (constant only) ln(mean) or SolveC with ln_r = ln_s = 0
<end of file>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -