*! ivreg2_p 1.0.10 30jul2023 *! author mes * 1.0.1: 25apr2002 original version * 1.0.2: 28jun2005 version 8.2 * 1.0.3: 1Aug2006 complete rewrite plus fwl option * 1.0.4: 26Jan2007 eliminated double reporting of #MVs * 1.0.5: 2Feb2007 small fix to allow fwl of just _cons * 1.0.6: 19Aug2007 replacement of "fwl" with "partial" in conjuction with new ivreg2 syntax * 1.0.7: 4Feb2010 version check update * 1.0.8: 30Jan2011 re-introduced stdp option (hadn't been supported after fwl/partial) * and added labelling of created residual variable * 1.0.9: 25Jan2015 Rewrite to accommodate new ivreg2 with legacy support; * passes control to matching ivreg2x_p predict program. * 1.0.10:30Jul2023 Change version of ivreg211_p to 11.2, tsrevar->fvrevar to handle FVs (cfb0) program define ivreg2_p * Minimum of version 8 required (earliest ivreg2 is ivreg28) version 8 * If estimation used current ivreg2, pass control to ivreg211 subroutine below. * If estimation used legacy ivreg2x, pass control to earlier version. if "`e(ivreg2cmd)'"=="ivreg2" { ivreg211_p `0' } else if "`e(ivreg2cmd)'"=="ivreg210" { ivreg210_p `0' } else if "`e(ivreg2cmd)'"=="ivreg29" { ivreg29_p `0' } else if "`e(ivreg2cmd)'"=="ivreg28" { ivreg28_p `0' } else { di as err "Error - ivreg2 estimation missing e(ivreg2cmd) macro" exit 601 } end * Main/current predict program: upgrade to v11.2 for FV handling program define ivreg211_p // version 8.2 version 11.2 syntax newvarname [if] [in] , [XB Residuals stdp] marksample touse, novarlist * Check ivreg2 version is compatible. * fwl becomes partial starting in ivreg2 02.2.07 local vernum "`e(version)'" if ("`vernum'" < "03.0.00") | ("`vernum'" > "09.9.99") { di as err "Error: incompatible versions of ivreg2 and ivreg2_p." di as err "Currently installed version of ivreg2 is `vernum'" di as err "To update, from within Stata type " _c di in smcl "{stata ssc install ivreg2, replace :ssc install ivreg2, replace}" exit 601 } local type "`xb'`residuals'`stdp'" if "`type'"=="" { local type "xb" di in gr "(option xb assumed; fitted values)" } * e(partialcons) now always exists and is 1 or 0 if e(partial_ct) { * partial partial-out block if "`type'" == "residuals" { tempvar esample tempname ivres gen byte `esample' = e(sample) * Need to strip out time series operators *** and FVs *** local lhs "`e(depvar)'" // tsrevar `lhs', substitute fvrevar `lhs', substitute local lhs_t "`r(varlist)'" local rhs : colnames(e(b)) // tsrevar `rhs', substitute fvrevar `rhs', substitute local rhs_t "`r(varlist)'" if "`e(partial1)'" != "" { local partial "`e(partial1)'" } else { local partial "`e(partial)'" } // tsrevar `partial', substitute fvrevar `partial', substitute local partial_t "`r(varlist)'" if ~e(partialcons) { local noconstant "noconstant" } local allvars "`lhs_t' `rhs_t'" * Partial-out block. Uses estimatation sample to get coeffs, markout sample for predict _estimates hold `ivres', restore foreach var of local allvars { tempname `var'_partial qui regress `var' `partial' if `esample', `noconstant' qui predict double ``var'_partial' if `touse', resid local allvars_partial "`allvars_partial' ``var'_partial'" } _estimates unhold `ivres' tokenize `allvars_partial' local lhs_partial "`1'" mac shift local rhs_partial "`*'" tempname b mat `b'=e(b) mat colnames `b' = `rhs_partial' * Use forcezero? tempvar xb mat score double `xb' = `b' if `touse' gen `typlist' `varlist' = `lhs_partial' - `xb' label var `varlist' "Residuals" } else { di in red "Option `type' not supported with -partial- option" error 198 } } else if "`type'" == "residuals" { tempname lhs lhs_t xb local lhs "`e(depvar)'" // tsrevar `lhs', substitute fvrevar `lhs', substitute local lhs_t "`r(varlist)'" qui _predict `typlist' `xb' if `touse' gen `typlist' `varlist'=`lhs_t'-`xb' label var `varlist' "Residuals" } * Must be either xb or stdp else { _predict `typlist' `varlist' if `touse', `type' } end