OVERIDXT: Stata module to test validity of instruments in xtivreg
*! overidxt from overid V1.5.0 C F Baum, Vince Wiggins, Steve Stillman * overid V1.1 C F Baum 9B19 * Ref: Davidson and MacKinnon, Estimation and Inference in Econometrics, p.236 * Wooldridge, Econometric Analysis of Cross-Section and Panel Data, p.123 * V1.3: add handling of weights, guard against use with robust * V1.35: correct handling of inst list * V1.4.0: adds support for xtivreg, fe * V1.4.1: standard error msg re xtivreg * V1.4.2: move to ivreg 5.00.09 for collinear instruments correction * V1.4.3: fixed bug with lagged covariates in xtivreg * V1.4.4: suppress constant in aux reg if no constant in orig eqn, per ivreg2 * V1.4.5: 80-byte bug looking for _cons * V1.5.0: support only xtivreg, fe program define overidxt, rclass version 6.0 syntax if "`e(cmd)'" ~= "xtivreg" { di in r "overidxt only works after xtivreg, fe" error 301 } if "`e(cmd)'" == "ivreg" & "`e(version)'" < "05.00.09" { di in red "overidxt requires version 5.0.9 or later of ivreg" di in red "type -update query- and follow the instructions" /* */ " to update your Stata" exit 198 } if "`e(cmd)'" == "xtivreg" & "`e(version)'" < "1.1.4" { di in red "overidxt requires version 1.1.4 or later of xtivreg" di in red "type -update query- and follow the instructions" /* */ " to update your Stata" exit 198 } if "`e(cmd)'" == "xtivreg" & "`e(model)'" ~= "fe" { di in red "test is only valid with fixed effects models" exit 198 } if "`e(vcetype)'" == "Robust" { di in red "test not valid with robust covariance estimates" exit 198 } if "`e(wtype)'" == "aweight" | "`e(wtype)'" == "iweight" { di in red "test not valid with aweights or iweights" exit 198 } tempname res rssiv ivk inst inst2 regest touse weight idvar /* idvar in fixed effect model */ local idvar `e(ivar)' /* determine whether _cons in original list (includes ,noc hanscons) */ tempname b mat `b' = e(b) local x : colnames `b' * FRAGILE FOR LISTS > 80 BYTES * if index("`x'","_cons")==0 { local noc ",noc" } local nc : word count `x' local hc 0 forv i = 1 /`nc' { local w : word `i' of `x' if "`w'" == "_cons" { local hc 1 } } if `hc' == 0 { local noc ",noc" } /* calculate degree of overid */ if "`e(cmd)'" == "ivreg" { local ivk = e(df_m) } else if "`e(cmd)'" == "xtivreg" { local ivk = e(df_rz) } /* instrument list */ local inst `e(insts)' gen byte `touse' = e(sample) /* fetch residuals and calc their SS */ if "`e(cmd)'" == "ivreg" { qui predict double `res' if `touse' , res } else if "`e(cmd)'" == "xtivreg" { qui predict double `res' if `touse' , e } local rssiv = e(rss) local inst2 `e(insts)' local weight "" if "`e(wexp)'" != "" { local weight "[`e(wtype)'`e(wexp)']" } /* regress IV residuals on instrument list */ capture { estimates hold `regest' tsrevar `res' `inst2' xtreg `r(varlist)' `weight' if `touse', fe i(`idvar') return scalar N = e(N) return scalar overid = return(N)*(1.0-e(rss)/`rssiv') return scalar df = `ivk'-e(df_r) return scalar p = chiprob(return(df),return(overid)) estimates unhold `regest' } if return(df) == 0 { di in red _n "There are no overidentifying restrictions." exit } di in gr _n "Test of overidentifying restrictions: " /* */ in ye %7.3f return(overid) in gr /* */ in gr " Chi-sq(" %2.0f in ye return(df) /* */ in gr ") P-value = " in ye %6.0g return(p) end exit 