📄 svyheckman.ado
字号:
`first' probit `seldep' `selind' `wgt' /*
*/ if `touse', asis `selnc' `soffopt'
`do2' matrix `Vprb' = get(VCE)
predict double `pxb', xb, if `touse'
mat `bprb' = get(_b)
gen double `mills' = normd(`pxb') / normprob(`pxb')
return scalar prbll = e(ll)
/* Regression strictly to test indep */
if "`offset'" != "" {
local origdep `depvar'
tempname depvar
gen double `depvar' = `origdep' - `offset'
}
if "`wtype'" == "aweight" {
tempvar wt
gen double `wt' `wtexp'
sum `wt' if `touse', meanonly
replace `wt' = `wt' * r(N) / r(sum)
sum `wt' if `touse' & `seldep'
scalar `wtobs' = r(sum)
/* required, e(N) is rounded */
regress `depvar' `varlist' [iweight=`wt'], /*
*/ `constant', /*
*/ if `touse' & `seldep'
}
else {
regress `depvar' `varlist' `wgt', /*
*/ `constant', if `touse' & `seldep'
scalar `wtobs' = e(N)
}
return scalar regll = -0.5 * `wtobs' * /*
*/ ( ln(2*_pi) + ln(e(rss)/`wtobs') + 1 )
/* Compute delta-bar */
gen double `delthat' = `mills' * (`mills' + `pxb')
sum `delthat' if `touse' & `seldep', meanonly
scalar `deltbar' = r(mean)
/* Second-step -- regression w/ Mills */
if "`constant'" == "" {
tempvar one
gen byte `one' = 1
}
regress `depvar' `varlist' `one' `mills' `wgt', nocons, /*
*/ if `touse' & `seldep'
mat `breg' = get(_b)
/* Heckman's two-step consistent
* estimates of sigma and rho */
tempname rss ebar adj ratio
if e(rss) == . {
tempvar e
predict double `e' if `touse', resid
replace `e' = sum(`e'^2)
scalar `rss' = `e'[_N]
if `rss' == . {
error 1400
}
}
else scalar `rss' = e(rss)
scalar `ebar' = `rss' / e(N)
scalar `sigma' = sqrt(`ebar' + `deltbar'*_b[`mills']^2)
scalar `rho' = _b[`mills'] / `sigma'
scalar `rho1' = `rho'
if abs(`rho') > 1 & `rhometh' >= 1 & `rhometh' <= 2 {
scalar `rho' = `rho'/abs(`rho')
if "`twostep'" != "" {
noi di as txt "note: two-step estimate " /*
*/ "of rho = " `rho1' " is being " /*
*/ "truncated to " `rho'
}
if `rhometh' == 2 {
scalar `sigma' = _b[`mills']*`rho'
}
}
if `sigma' == 0 {
scalar `sigma' = .001
}
if `rho' == . {
scalar `rho' = 0
}
if "`twostep'" != "" {
if "`lvmills'" != "" {
rename `mills' `lvmills'
local mills `lvmills'
label var `mills' "nonselection hazard"
}
noi Heck2 `breg' `rho' `sigma' `bprb' `Vprb' /*
*/ `depvar' "`varlist'" "`constant'" "`seldep'" /*
*/ "`selind'" "`selnc'" "`mills'" "`delthat'" /*
*/ "`touse'" "`rhometh'" "`rho1'"
}
else {
scalar `athrho' = max(min(`rho',.85), -.85)
scalar `athrho' = 0.5 * log((1+`athrho') / /*
*/ (1-`athrho'))
scalar `lnsigma' = ln(`sigma')
mat `b0' = `breg'[1,1..(colsof(`breg')-1)] , /*
*/ `bprb' , `athrho' , `lnsigma'
}
}
end
/* Note: Heck2 assumes that the regression w/ a Mills ratio is the
* current set of estimates */
program define Heck2, eclass /* BetaReg rho sigma Cov(probit)
RegVars RecCons PrbVars Mills touse */
args b /* regression Beta
*/ rho /*
*/ sigma /*
*/ bprb /* probit Beta
*/ Vprb /* probit VCE
*/ depvar /* dependent variable
*/ varlist /* independent varlist
*/ constant /* "" or "noconstant"
*/ seldep /* selection eqn dependent variable
*/ selind /* selection eqn indep varlist
*/ selnc /* selection eqn : "" or "noconstant"
*/ mills /* Mills' ratio
*/ delthat /*
*/ touse /* To use variable
*/ rhometh /* method of using rho
*/ rho1 /* original two-step rho if outide -1,1 */
tempname XpX1 F Q rho2 VBm
/* Compute Heckman's two-step consistent estimates of Cov */
/* Get X'X inverse from the
* second-step regression */
if e(rmse) != 0 {
matrix `XpX1' = get(VCE) / e(rmse)^2
}
else {
di as err /*
*/ "insufficient information in sample to estimate heckman model"
exit 2000
}
/* Heckman's adjustment to Cov */
local fulnam `varlist'
if "`constant'" == "" {
tempvar one
g byte `one' = 1
local fulnam "`fulnam' _cons"
}
local fulnam "`fulnam' lambda"
local kreg : word count `fulnam'
local kreg1 = `kreg' + 1
qui mat accum `F' = `varlist' `one' `mills' `selind' [iw=`delthat'], /*
*/ `selnc', if `touse' & `seldep'
mat `F' = `F'[1..`kreg', `kreg1'...]
mat rowname `F' = `fulnam'
scalar `rho2' = `rho' * `rho'
mat `Q' = `rho2' * `F'*`Vprb'*`F''
/* Finish the variance computation */
tempvar rho2del
if (`rho' < -1 | `rho' > 1) & `rhometh' == 3 {
scalar `rho2' = 1
}
qui gen double `rho2del' = 1 - `rho2' * `delthat' if `touse'
qui mat accum `VBm' = `varlist' `one' `mills' [iw=`rho2del'], /*
*/ nocons, if `touse' & `seldep'
mat `VBm' = `sigma'^2 * `XpX1' * (`VBm' + `Q') * `XpX1'
/* Build the set of full eqn names */
local eqnam
tokenize `fulnam'
local i 1
while `i' < `kreg' {
local eqnam `eqnam' `depvar':``i''
local i = `i' + 1
}
if substr("`seldep'",1,2) != "__" {
local selname `seldep'
}
else local selname select
local kprb : word count `selind'
local i 1
tokenize `selind'
while `i' <= `kprb' {
local eqnam `eqnam' `selname':``i''
local i = `i' + 1
}
if "`selnc'" == "" {
local eqnam `eqnam' `selname':_cons
local kprb = `kprb' + 1
}
local eqnam `eqnam' mills:lambda
/* Put model and selection
* equation together
* Quicker w/ matrix expr, but would
* be hard to understand */
tempname bfull Vfull zeros Vmills CovMill zeroPrb b0 bmills
local kreg0 = `kreg' - 1
mat `b0' = `b'[1,1..`kreg0']
mat `bmills' = `b'[1,`kreg']
mat `bfull' = `b0', `bprb' , `bmills'
mat `Vmills' = `VBm'[`kreg', `kreg']
mat `CovMill' = `VBm'[1..`kreg0', `kreg']
mat `VBm' = `VBm'[1..`kreg0', 1..`kreg0']
mat `zeros' = J(`kreg0', `kprb', 0)
mat `zeroPrb' = J(`kprb', 1, 0)
mat `VBm' = /*
*/ ( `VBm' , `zeros' , `CovMills' \ /*
*/ `zeros'' , `Vprb' , `zeroPrb' \ /*
*/ `CovMills'' , `zeroPrb'' , `Vmills' )
mat `VBm' = (`VBm' + `VBm'') / 2
mat colnames `bfull' = `eqnam'
mat rownames `VBm' = `eqnam'
mat colnames `VBm' = `eqnam'
qui count if `touse'
capture eret post `bfull' `VBm', obs(`r(N)')
if _rc {
if _rc == 506 {
di as err "estimate of rho outside the interval " /*
*/ "[-1, 1] has led to a covariance matrix"
di as err "that is not positive definite"
* mat `VBm' = 0*`VBm'
mat `VBm'[1, 1] = 0*`VBm'[1..`kreg0', 1..`kreg0']
}
eret post `bfull' `VBm', obs(`r(N)')
}
eret scalar N = `r(N)'
capture qui test `varlist', min
if _rc == 0 {
eret scalar chi2 = `r(chi2)'
eret scalar df_m = `r(df)'
eret scalar p = `r(p)'
}
qui count if `seldep' == 0 & `touse'
eret scalar N_cens = r(N) /* early, sic */
eret local chi2type "Wald"
eret local title2 "(regression model with sample selection)"
eret local title "Heckman selection model -- two-step estimates"
if substr("`mills'", 1, 2) != "__" {
eret local mills `mills'
}
eret scalar rho = `rho'
if `rho1' != `rho' {
eret scalar rho1 = `rho1'
}
eret scalar sigma = `sigma'
eret scalar lambda = [mills]_b[lambda]
eret scalar selambda = [mills]_se[lambda]
eret local predict "heckma_p"
end
/* Fit miss-specified model. */
program define FitMiss, rclass
syntax varlist if [, /*
*/ constant /*
*/ mlopts(string) /*
*/ offset(passthru) /*
*/ sel(passthru) /*
*/ MEFF /*
*/ MEFT /*
*/ * /*
*/ ]
svyopts junk junk2 junk3, `options'
local subcond `s(subpop)'
tempname touse
mark `touse' `if'
eret clear
if "`meff'`meft'" != "" {
di _n as txt "Computing misspecified " ///
as res "heckman" ///
as txt " model for meff/meft computation:"
if "`subcond'" != "" {
local mysubtouse (`touse' & `subcond' != 0)
}
else local mysubtouse `touse'
heckman `varlist' /*
*/ if `mysubtouse', /*
*/ `constant' /*
*/ `mlopts' /*
*/ `offset' /*
*/ `sel' /*
*/
}
return local results `meff'`meft'
end
/* process the selecton equation
[depvar =] indvars [, noconstant offset ]
*/
program define SelectEq
args seldep selind selnc seloff colon sel_eqn
gettoken depvar rest : sel_eqn, parse(" =")
gettoken equal rest : rest, parse(" =")
if "`equal'" == "=" {
unab depvar : `depvar'
c_local `seldep' `depvar'
}
else local rest `"`sel_eqn'"'
local 0 `"`rest'"'
syntax [varlist(numeric default=none)] /*
*/ [, noCONstant OFFset(varname numeric) ]
if "`constant'" != "" & "`varlist'" == "" {
di as err "no variables specified for selection equation"
exit 198
}
c_local `selind' `varlist'
c_local `selnc' `constant'
c_local `seloff' `offset'
end
exit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -