*! ivreset 1.0.08 4Feb2007 *! author mes * Z are instruments (L of them) and X are regressors (K of them) * 1.0.04 Fixed small bug in check for xtmodel * Fixed dof check in xtivreg2 * 1.0.05 Changed rescaling so that squares, cubes, etc are created then rescaled * 1.0.06 Removed rescaling, switched to -orthog- * Removed support for official ivreg * Fixed small bug in failed cstat reporting * 1.0.07 Added trap to catch usage after ivreg2 with fwl * 1.0.08 Refined trap program define ivreset, rclass sortpreserve version 8.0 local version 1.0.8 syntax [, POLYnomial(integer 2) RForm cstat small] if "`e(cmd)'" != "ivreg2" & "`e(cmd)'" != "regress" & /* */ "`e(cmd)'" != "ivreg3" & "`e(cmd)'" != "xtivreg2" { error 301 } if "`e(cmd)'" == "xtivreg2" & "`e(xtmodel)'" ~= "fe" { error 301 } if "`e(fwlcons)'" != "" { di in r "ivreset not allowed after ivreg2 with fwl option" error 499 } if "`cstat'" != "" { * Check that ivreg2 is installed when cstat option is requested capture findfile ivreg2.ado if _rc==601 { di as err "Error: installed ivreg2 required for cstat option" error 601 } } tempvar touse N yhat yhat2 yhat3 yhat4 tempname regest b * Default is to use Pesaran-Smith optimal forecast of y if "`rform'" == "" { local msg0 "Ramsey/Pesaran-Taylor RESET test" local msg2 "fitted value of y (X-hat*beta-hat)" } else { local msg0 "Ramsey/Pagan-Hall RESET test" local msg2 "reduced form prediction of y" } if "`cstat'" == "" { local msg3 "Wald" } else { local msg3 "C (GMM-distance)" } if "`e(vcetype)'"=="Robust" { local robust "robust" local msg3h "heteroskedastic-" } if "`e(clustvar)'"~="" { local clopt "cluster(`e(clustvar)')" local msg3c "cluster-" } if "`e(bw)'"~="" { local bwopt "bw(`e(bw)')" local kernopt "kernel(`e(kernel)')" local msg3a "autocorrelation-" } if "`e(wtype)'" != "" { local wtexp `"[`e(wtype)'`e(wexp)']"' } gen `touse'=e(sample) mat `b' = e(b) local rhs : colnames `b' local rhsct : word count `rhs' local depvar "`e(depvar)'" local df_m = e(df_m) if "`e(cmd)'" != "regress" { * Block for all IV commands local endo "`e(instd)'" local insts "`e(insts)'" foreach vn of local rhs { local tempvlist : subinstr local insts "`vn'" "`vn'" , /* */ word count(local isiv) if `isiv'==1 { local inexog "`inexog' `vn'" } } foreach vn of local insts { local tempvlist : subinstr local rhs "`vn'" "`vn'" , /* */ word count(local isregressor) if `isregressor'==0 { local exexog "`exexog' `vn'" } } * If endo is empty, it's OLS or HOLS, and if so, ignore exexog as well if "`endo'"=="" { local exexog } if e(cons)~=1 { local consflag 0 local consopt "nocons" } else { local consflag 1 } } else { * Block for simple regress local endo local exexog local inexog : subinstr local rhs "_cons" "", word count(local consflag) if `consflag'==0 { local consopt "nocons" } } * If no endogenous regressors, it's just a simple RESET test if "`endo'" == "" { local msg0 "Ramsey RESET test" local msg2 "fitted value of y (X*beta-hat)" } * Demeaning block for xtivreg2 if "`e(cmd)'" == "xtivreg2" { preserve tempvar ivar T_i depvar2 qui gen double `depvar2' = `depvar' qui gen `ivar' = `e(ivar)' sort `ivar' `touse' qui by `ivar' `touse': gen long `T_i' = _N if _n==_N & `touse' qui count if `T_i' < . * N_g minus 1 is additional degrees of freedom absorbed by the extra dummies local N_g=r(N) local allvars "`depvar' `inexog' `endo' `exexog'" qui foreach var of local allvars { tempname `var'_m by `ivar' `touse' : gen double ``var'_m'=sum(`var')/_N if `touse' by `ivar' `touse' : replace ``var'_m'=``var'_m'[_N] if `touse' & _n<_N by `ivar' `touse' : replace `var'=`var'-``var'_m'[_N] if `touse' } * Small degrees of freedom = N minus #regressors minus #fixed effects (+constant) * Large = N minus #fixed effects qui sum `depvar' if `touse' local N=r(N) * Use only large dof, not small. Subtract full number of fixed effects `N_g' local dof = `N' - `N_g' * nocons not part of xtopts - caught below local xtopts "dofminus(`N_g')" } if "`rform'" == "" { * Code for Pesaran-Smith test using "predicted" values "yhat"=xhat*Bhat (NOT x*Bhat) * Generate predicted values of endog regressors * In special case of no endog regressors (OLS or HOLS), exexog has also been set to empty * and yhat is just the usual OLS/HOLS yhat foreach vn of local endo { capture _estimates hold `regest', restore qui regress `vn' `inexog' `exexog' `wtexp' if `touse', `consopt' tempvar xh qui predict double `xh' if `touse', xb capture _estimates unhold `regest' local endohat "`endohat' `xh'" } local rhshat "`endohat' `inexog'" mat `b' = e(b) if `consflag' { local rhshat "`rhshat' _cons" } matrix colnames `b' = `rhshat' matrix score double `yhat' = `b' if `touse' } if "`rform'" != "" { * Code for Pagan-Hall test using reduced form predictions * In special case of no endog regressors (OLS or HOLS), exexog has also been set to empty * and yhat is just the usual OLS/HOLS yhat capture _estimates hold `regest', restore qui regress `depvar' `inexog' `exexog' `wtexp', `consopt' qui predict double `yhat', xb capture _estimates unhold `regest' } * Add mean back to yhat if xtivreg2 qui if "`e(cmd)'" == "xtivreg2" { tempname depvar_m by `ivar' `touse' : gen double `depvar_m'=sum(`depvar2')/_N if `touse' by `ivar' `touse' : replace `depvar_m'=`depvar_m'[_N] if `touse' & _n<_N by `ivar' `touse' : replace `yhat' =`yhat' +`depvar_m'[_N] if `touse' } * Generate squares, and cube/4th powers if requested. Always need yhat^2. * Orthogonalize if order>3. qui gen double `yhat2'=`yhat'^2 if `polynomial'==2 { local yhats "`yhat2'" local msg1 "square of " } if `polynomial'==3 { tempname yhat2o yhat3o qui gen double `yhat3'=`yhat'^3 orthog `yhat2' `yhat3' if `touse', gen(`yhat2o' `yhat3o') qui replace `yhat2'=`yhat2o' qui replace `yhat3'=`yhat3o' local yhats "`yhat2' `yhat3'" local msg1 "square and cube of " } if `polynomial'==4 { tempname yhat2o yhat3o yhat4o qui gen double `yhat3'=`yhat'^3 qui gen double `yhat4'=`yhat'^4 orthog `yhat2' `yhat3' `yhat4' if `touse', gen(`yhat2o' `yhat3o' `yhat4o') qui replace `yhat2'=`yhat2o' qui replace `yhat3'=`yhat3o' qui replace `yhat4'=`yhat4o' local yhats "`yhat2' `yhat3' `yhat4'" local msg1 "square, cube and 4th power of " } * Demean yhats if "`e(cmd)'" == "xtivreg2" { qui foreach var of local yhats { tempname `var'_m by `ivar' `touse' : gen double ``var'_m'=sum(`var')/_N if `touse' by `ivar' `touse' : replace ``var'_m'=``var'_m'[_N] if `touse' & _n<_N by `ivar' `touse' : replace `var'=`var'-``var'_m'[_N] if `touse' } } * Artificial regression test (default) if "`cstat'"=="" { capture _estimates hold `regest', restore if "`endo'" != "" { capture ivreg2 `depvar' `inexog' `yhats' (`endo'=`exexog') `wtexp' if `touse', /* */ `small' `xtopts' `robust' `clopt' `bwopt' `kernopt' `consopt' } else { * No endogenous regressors, so ignore excluded exog (if any) as well capture ivreg2 `depvar' `inexog' `yhats' `wtexp' if `touse', /* */ `small' `xtopts' `robust' `clopt' `bwopt' `kernopt' `consopt' } if "`e(cmd)'" == "xtivreg2" { local df_aug = (`N_g'+e(df_m)-(`polynomial'-1)) } else { local df_aug = (e(df_m)-(`polynomial'-1)) } if `df_aug' < `df_m' { di as err "Error - collinearities in augmented regression equation." di as err "If using higher order polynomials, try reducing the order." error 103 } else { capture test `yhats' return scalar df=r(df) return scalar p=r(p) if "`small'" == "" { return scalar chi2=r(chi2) } else { return scalar F=r(F) return scalar df_r=r(df_r) } } capture _estimates unhold `regest' } * Cstat test (GMM distance) if "`cstat'" != "" { capture _estimates hold `regest', restore * If endo is empty, so is exexog and it's just an LM test qui ivreg2 `depvar' `inexog' (`endo'=`exexog' `yhats') `wtexp' if `touse', /* */ orthog(`yhats') `small' `xtopts' `robust' `clopt' `bwopt' `kernopt' `consopt' if e(cstat) > 0 & e(cstat) < . { tempname cstat scalar `cstat'=e(cstat) return scalar df=e(cstatdf) return scalar p=e(cstatp) if "`small'" == "" { return scalar chi2=`cstat' } else { return scalar df_r=e(Fdf2)-return(df) return scalar F=`cstat'/return(df)*return(df_r)/e(N) } } capture _estimates unhold `regest' } di in g "`msg0'" di in g "Test uses `msg1'`msg2'" di in g "Ho: E(y|X) is linear in X" if return(chi2)~=. | return(F)~=. { if "`small'"=="" { di in g "`msg3' test statistic: " /* */ _col(35) in g "Chi-sq(" return(df) ") = " /* */ in y %5.2f return(chi2) /* */ _col(55) in g "P-value = " /* */ in y %5.4f return(p) } else { di in g "`msg3' test statistic: " /* */ _col(35) in g "F(" return(df) "," return(df_r) ") = " /* */ in y %5.2f return(F) /* */ _col(55) in g "P-value = " /* */ in y %5.4f return(p) } if "`msg3h'`msg3c'`msg3a'" ~= "" { di in g "Test is `msg3h'`msg3c'`msg3a'robust" } } else { di as err "Error in estimating augmented equation - statistic not reported" } end