📄 ivtobit.ado
字号:
*! version 1.1.5 03apr2005
// BPP
program define ivtobit, eclass byable(onecall)
if _by() {
local BY `"by `_byvars'`_byrc0':"'
}
`BY' _vce_parserun ivtobit, jkopts(eclass) : `0'
if "`s(exit)'" != "" {
exit
}
version 8.2
if replay() {
if "`e(cmd)'" != "ivtobit" {
error 301
}
if _by() {
error 190
}
if "`e(method)'" == "ml" {
MLDisplay `0'
}
else {
TSDisplay `0'
}
exit
}
`BY' Estimate `0'
end
program define Estimate, eclass byable(recall) sortpreserve
// Portions of syntax parsing code are from ivreg.ado
local n 0
gettoken lhs 0 : 0, parse(" ,[") match(paren)
IsStop `lhs'
if `s(stop)' {
error 198
}
while `s(stop)'==0 {
if "`paren'"=="(" {
local n = `n' + 1
if `n'>1 {
capture noi error 198
di as error `"syntax is "(all instrumented variables = instrument variables)""'
exit 198
}
gettoken p lhs : lhs, parse(" =")
while "`p'"!="=" {
if "`p'"=="" {
capture noi error 198
di as error `"syntax is "(all instrumented variables = instrument variables)""'
di as error `"the equal sign "=" is required"'
exit 198
}
local end`n' `end`n'' `p'
gettoken p lhs : lhs, parse(" =")
}
tsunab end`n' : `end`n''
tsunab exog`n' : `lhs'
}
else {
local exog `exog' `lhs'
}
gettoken lhs 0 : 0, parse(" ,[") match(paren)
IsStop `lhs'
}
local 0 `"`lhs' `0'"'
tsunab exog : `exog'
tokenize `exog'
local lhs "`1'"
local 1 " "
local exog `*'
// Eliminate vars from `exog1' that are in `exog'
Subtract inst : "`exog1'" "`exog'"
// `lhs' contains depvar,
// `exog' contains RHS exogenous variables,
// `end1' contains RHS endogenous variables, and
// `inst' contains the additional instruments
local lhsname `lhs'
local lhsstr : subinstr local lhsname "." "_"
local exogname `exog'
local end1name `end1'
local instname `inst'
_find_tsops `lhs' `exog' `end1' `inst'
if `r(tsops)' {
qui tsset
tsrevar `lhs'
local lhs `r(varlist)'
tsrevar `end1'
local end1 `r(varlist)'
tsrevar `exog'
local exog `r(varlist)'
tsrevar `inst'
local inst `r(varlist)'
}
// Check for collinearity in RHS variables
foreach x in end1 exog inst {
local old`x' ``x''
qui _rmcoll ``x''
local `x' "`r(varlist)'"
local dropped : list old`x' - `x' // `x' resolves to a local
foreach y of local dropped {
local j : list posof "`y'" in old`x'
local y2 : word `j' of ``x'name'
noi di as text "note: `y2' dropped due to collinearity"
}
}
// Now parse the remaining syntax
syntax [if] [in] [fw pw iw / ] , [ Mle TWOstep Robust ///
CLuster(varname) SCore(string) FIRST noLOg ///
LL1 LL2(numlist min=1 max=1) UL1 UL2(numlist min=1 max=1) ///
Level(cilevel) FROM(string) ///
NRTOLerance(string) * ]
local mloptions `"`options'"'
if _by() {
_byoptnotallowed score() `"`score'"'
}
marksample touse
markout `touse' `lhs' `exog' `end1' `inst'
local end1_ct : word count `end1'
local inst_ct : word count `inst'
// Check order condition
if `end1_ct' == 0 {
di as error "no endogenous variables; use {cmd:tobit} instead"
exit 198
}
if `end1_ct' > `inst_ct' {
di as error "equation not identified; must have at " ///
"least as many instruments "
di as error "not in the regression as there are " ///
"instrumented variables"
exit 481
}
// Syntax checking
if "`ll1'`ll2'`ul1'`ul2'" == "" {
di as error "must specify censoring point"
exit 198
}
if "`ll1'" != "" & "`ll2'" != "" {
di as error "options ll and ll(#) may not be combined"
exit 184
}
if "`ul1'" != "" & "`ul2'" != "" {
di as error "options ul and ul(#) may not be combined"
exit 184
}
if "`mle'" != "" & "`twostep'" != "" {
di as error "cannot specify both mle and twostep options"
exit 198
}
local estimator "`mle'`twostep'"
if "`estimator'" == "" {
local estimator "mle"
}
if "`robust'`cluster'" != "" & ///
`=index("`mloptions'", "vce(")' > 0 {
if "`cluster'" != "" {
di as error "options vce() and cluster() may not be combined"
}
else {
di as error "options vce() and robust may not be combined"
}
exit 198
}
if "`estimator'" == "twostep" & ///
"`robust'`cluster'`score'`log'`from'`mloptions'`nrtolerance'" != "" {
di as error "two-step estimator only allows the first and level() options"
exit 198
}
if "`weight'" != "" {
local wgt `"[`weight'=`exp']"'
}
if "`weight'" == "pweight" | "`cluster'" != "" {
local robust "robust"
}
if "`weight'" != "" & "`weight'" != "fweight" & ///
"`estimator'" == "twostep" {
di as error "may only use fweights with two-step estimator"
exit 498
}
if "`cluster'" != "" {
local clusopt "cluster(`cluster')"
}
if "`score'" != "" {
local needed = 1 + `end1_ct' + (`end1_ct'+1)*(`end1_ct'+2)/2
local n : word count `score'
if `n' == 1 & substr("`score'", -1, 1) == "*" {
local score = substr("`score'",1,length("`score'")-1)
local scorestr ""
local scoretmp ""
forvalues i = 1/`needed' {
confirm new var `score'`i'
local scorestr "`scorestr' `score'`i'"
tempvar score`i'
local scoretmp "`scoretmp' `score`i''"
}
}
else {
local 0 `score'
syntax newvarlist
local score `varlist'
local n : word count `score'
if `n' != `needed' {
di as error "number of variables in score() option must be `needed'"
exit 198
}
confirm new var `score'
local scoretmp ""
forvalues i = 1/`needed' {
tempvar score`i'
local scoretmp "`scoretmp' `score`i''"
}
local scorestr "`score'"
}
local scoreml "score(`scoretmp')"
}
if "`nrtolerance'" == "" {
local nrtolerance 1e-7
}
mlopts mlopts, `mloptions'
// Do 2SLS ignoring censoring to get some
// preliminary results
qui regress `lhs' `end1' `exog' `inst' if `touse' `wgt'
if ( e(N) == 0 | e(N) >= . ) {
exit 2000
}
tempname b
mat `b' = e(b)
qui replace `touse' = 0 if !(e(sample))
local varlist : colnames(`b')
tokenize `varlist'
local i : word count `varlist'
if trim(`"``i''"') != "_cons" {
di as error "may not drop constant"
exit 399
}
local `i' // These two lines essentially
local varlist `"`*'"' // remove _cons from varlist
// If any of the endogenous variables were dropped, exit
// with an r(498).
tokenize `varlist'
local i = 1
foreach x of local end1 {
if `"``i''"' != `"`x'"' {
di as error "may not drop an endogenous variable"
exit 498
}
local i = `i' + 1
}
local exog : subinstr local varlist "`end1'" ""
local exog : subinstr local exog "`inst'" ""
local inst : subinstr local varlist "`end1'" ""
local inst : subinstr local inst "`exog'" ""
tokenize `exog' // Clean up exog and remove
local exog `"`*'"' // extraneous white space
local exog_ct : word count `exog'
tokenize `inst' // Clean up inst and remove
local inst `"`*'"' // extraneous white space
local inst_ct : word count `inst'
// Now figure out what the ll() and ul() opts are
qui summ `lhs' if `touse', meanonly
local ulopt ""
local llopt ""
local tobitll = `r(min)' - 1
local tobitul = `r(max)' + 1
if "`ll1'" != "" {
local llopt "ll(`r(min)')"
local tobitll `r(min)'
}
else if "`ll2'" != "" {
local llopt "ll(`ll2')"
local tobitll `ll2'
}
if "`ul1'" != "" {
local ulopt "ul(`r(max)')"
local tobitul `r(max)'
}
else if "`ul2'" != "" {
local ulopt "ul(`ul2')"
local tobitul `ul2'
}
if `tobitul' <= `tobitll' {
di as error "no uncensored observations"
exit 2000
}
if "`estimator'" == "twostep" {
// First set up D(Pi)
// The selection matrix is just the identity matrix
// if we include the exogenous variables after the other insts.
local totexog_ct = `exog_ct' + `inst_ct'
tempname DPi
mat `DPi' = J(`totexog_ct'+1, `end1_ct'+`exog_ct'+1, 0)
mat `DPi'[`inst_ct'+1, `end1_ct'+1] = I(`exog_ct'+1)
// Now do the first-stage regressions, fill in DPi and
// save fitted values and residuals
tempname junk
local fitted ""
local resids ""
local qui "qui"
if "`first'" != "" {
local qui ""
}
local i = 1
if `end1_ct' == 1 {
`qui' di "First stage regression"
}
else {
`qui' di "First stage regressions"
}
foreach y of local end1 {
`qui' regress `y' `inst' `exog' `wgt' if `touse', ///
level(`level')
mat `junk' = e(b)
mat `DPi'[1, `i'] = `junk' '
tempvar fitted`i' resids`i'
qui predict double `fitted`i'' if `touse', xb
qui predict double `resids`i'' if `touse', residuals
local fitted "`fitted' `fitted`i''"
local resids "`resids' `resids`i''"
local i = `i' + 1
}
// 2SIV estimates
// We also use these 2SIV estimates for exog. test
cap qui tobit `lhs' `end1' `exog' `resids' ///
`wgt' if `touse', `llopt' `ulopt'
tempname beta2s b2s l2s var2s chi2exog chi2exdf
mat `beta2s' = e(b)
mat `b2s' = `beta2s'[1, 1..`end1_ct']
// Do the exog. test while we're at it.
qui test `resids'
scalar `chi2exog' = r(F)/r(df)
scalar `chi2exdf' = r(df)
// Next, estimate the reduced-form alpha
// alpha does not contain the params on `resids'
// Also get lambda
cap qui tobit `lhs' `inst' `exog' `resids' ///
`wgt' if `touse', `llopt' `ulopt'
tempname b alpha lambda
mat `b' = e(b)
mat `alpha' = J(1, `totexog_ct'+1, 0)
mat `alpha'[1, 1] = `b'[1, 1..`totexog_ct']
mat `alpha'[1, `totexog_ct'+1] = ///
`b'[1, `totexog_ct'+`end1_ct'+1]
mat `lambda' = `b'[1, `totexog_ct'+1..`totexog_ct'+`end1_ct']
// Build up the omega matrix
tempname omega var
mat `var' = e(V)
mat `omega' = J(`totexog_ct'+1, `totexog_ct'+1, 0)
// First term is J_aa inverse, which is cov matrix
// from reduced-form tobit
mat `omega'[1, 1] = `var'[1..`totexog_ct', 1..`totexog_ct']
local j = `totexog_ct'+`end1_ct'+1
mat `omega'[`totexog_ct'+1, `totexog_ct'+1] = `var'[`j',`j']
forvalues i = 1/`totexog_ct' {
mat `omega'[`totexog_ct'+1, `i'] = `var'[`j', `i']
mat `omega'[`i', `totexog_ct'+1] = `var'[`i', `j']
}
tempvar ylb
qui gen double `ylb' = 0
local i = 1
foreach var of varlist `end1' {
qui replace `ylb' = `ylb' + ///
`var'*(`lambda'[1,`i'] - `b2s'[1, `i']) ///
if `touse'
local i = `i' + 1
}
qui regress `ylb' `inst' `exog' `wgt' if `touse'
tempname V
mat `V' = e(V)
mat `omega' = `omega' + `V'
tempname omegai
mat `omegai' = inv(`omega')
// Newey answer
tempname finalb finalv
mat `finalv' = inv(`DPi'' * `omegai' * `DPi')
mat `finalb' = `finalv' * `DPi'' * `omegai' * `alpha''
mat `finalb' = `finalb''
// Fill in orig names for end1, exog and inst - timeseries ops.
foreach x in end1 exog inst {
local new`x' ``x''
foreach y of local `x' {
local j : list posof "`y'" in old`x'
local y2 : word `j' of ``x'name'
local new`x' : subinstr local new`x' "`y'" "`y2'"
}
local `x' `new`x''
}
loc names `end1' `exog' _cons
mat colnames `finalb' = `names'
mat colnames `finalv' = `names'
mat rownames `finalv' = `names'
qui summ `touse' `wgt' , meanonly
local capn = r(sum)
eret post `finalb' `finalv', depname(`lhsname') o(`capn') ///
esample(`touse')
eret scalar chi2_exog = `chi2exog'
eret scalar df_exog = `chi2exdf'
eret scalar p_exog = chiprob(`chi2exdf', `chi2exog')
qui test `end1' `exog'
eret scalar chi2 = r(chi2)
eret scalar df_m = r(df)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -