*! regdiag -- calculate and store diagnostics for the most recent regression *! version 1.0.1 Sean Becketti January 21, 1994 STB-15: sts4 * version 1.0.0, August 1993 * version 1.0.1, 1/21/94: changed _N to `last' in DW test to fix MV problem. program define regdiag version 3.1 local if "opt pre" local in "opt pre" local options "Aic AICC ALl ARch AR2 Dw Fpe H HQ Lags(int 0) LM *" parse "`*'" local star "`options'" local sif "`if'" local sin "`in'" local if local in local options "MDF(int 0) Mdl Normal Pc Q RBar2 Residual(str) R2 Sc Time" parse ",`star'" local if "`sif'" local in "`sin'" quietly { /* Was the most recent estimation command one we are prepared to handle? */ local cmd "$S_E_cmd" if !(("`cmd'"=="regress") | ("`cmd'"=="fit") | ("`cmd'"=="tsfit") | ("`cmd'"=="tsreg")) { if "`cmd'"=="" { di in re "no previous estimates" } else { di in re "cannot analyze results of estimation command: `cmd'" } error 98 } local ifts = ("`cmd'"=="tsfit") | ("`cmd'"=="tsreg") /* Restore the previous equation and calculate some of the quantities needed in many of the formulae. */ `cmd' /* reload the estimation results */ if "`in'"=="" { local in "$S_E_in" } if "`if'"=="" { local if "$S_E_if" } tempname N K Rbar2 rmse R2 s2 scalar `N' = _result(1) if `mdf'>0 { scalar `K' = `mdf' } else if `ifts' { scalar `K' = $S_E_K } else { scalar `K' = `N' - _result(5) } scalar `rmse' = _result(9) scalar `Rbar2' = _result(8) scalar `R2' = _result(7) scalar `s2' = `rmse'^2 * (`N'-`K')/`N' /* ML estimate of sigma^2 */ /* Which diagnostics are requested? */ local all = "`all'"!="" /* all diagnostics */ local time = "`time'"!="" /* standard set of TS diagnostics */ local aic = "`aic'"!="" | `all' | `time' /* standard */ local aicc = "`aicc'"!="" | `all' local arch = "`arch'"!="" | `all' | `time' /* standard */ local dw = "`dw'"!="" | `all' | `time' /* standard */ local fpe = "`fpe'"!="" | `all' local h = "`h'"!="" | `all' local hq = "`hq'"!="" | `all' local lm = "`lm'"!="" | `all' | `time' /* standard */ local mdl = "`mdl'"!="" | `all' local normal = "`normal'"!="" | `all' | `time' /* standard */ local pc = "`pc'"!="" | `all' local q = "`q'"!="" | `all' | `time' /* standard */ local rbar2 = "`rbar2'"!="" | "`ar2'"!="" | `all' local r2 = "`r2'"!="" | `all' local sc = "`sc'"!="" | `all' | `time' /* standard */ /* Either calculate residuals or store the user-supplied residuals. */ local ifuser = "`residua'"!="" /* Did the user supply the residuals? */ if `ifuser' { conf v `residua' local res "`residua'" sum `res' `if' `in' scalar `N' = _result(1) scalar `s2' = _result(4)*(`N'-1)/`N' scalar `rmse' = sqrt(_result(4)*(`N'-1)/(`N'-`K')) } else { tempvar res predict double `res', resid /* use ordinary residuals */ } tempvar touse mark `touse' `if' `in' markout `touse' `res' _crcnuse `touse' local N $S_1 local first=$S_3 local last=$S_4 local in "in `first'/`last'" local gaps=$S_2 /* Eliminate tests that can't tolerate gaps. */ if `gaps' { local if "if `touse'" local h 0 local q 0 } else { local if } /* Calculate the model selection statistics. */ if `aic' { global S_E_AIC = log(`s2') + 2*`K'/`N' local x = round($S_E_AIC,.001) noi di _skip(15) in gr "AIC: " in ye "`x'" } if `aicc' { global S_E_AICC = log(`s2') + (`N'+`K')/(`N'-`K'-2) local x = round($S_E_AICC,.001) noi di _skip(14) in gr "AICC: " in ye "`x'" } if `fpe' { global S_E_FPE = `s2'*(`N'+`K')/(`N'-`K') local x = round($S_E_FPE,.001) noi di _skip(15) in gr "FPE: " in ye "`x'" } if `hq' { global S_E_HQ = log(`s2') + 2*`K'*log(log(`N'))/`N' local x = round($S_E_HQ,.001) noi di _skip(16) in gr "HQ: " in ye "`x'" } if `mdl' { parse "$S_E_vl", parse(" ") mac shift matrix accum xx = `*' `if' `in', $S_E_cons global S_E_MDL = log(`N'*`s2') + log(det(xx))/`N' local x = round($S_E_MDL,.001) noi di _skip(15) in gr "MDL: " in ye "`x'" } if `pc' { global S_E_PC = `rmse'^2 * (1 + `K'/`N') local x = round($S_E_PC,.001) noi di _skip(16) in gr "PC: " in ye "`x'" } if `rbar2' { if `ifuser' { noi di in re "Can't calculate R-squared from user-supplied residuals" error 98 } global S_E_aR2 = `Rbar2' local x = round($S_E_aR2,.01) noi di in gr "adjusted R-squared: " in ye "`x'" } if `r2' { if `ifuser' { noi di in re "Can't calculate R-squared from user-supplied residuals" error 98 } global S_E_R2 = `R2' local x = round($S_E_R2,.01) noi di _skip(9) in gr "R-squared: " in ye "`x'" } if `sc' { global S_E_SC = log(`s2') + log(`N')*`K'/`N' local x = round($S_E_SC,.001) noi di in gr " Schwarz criterion: " in ye "`x'" } /* Now calculate the diagnostics which are more complicated functions of the residuals. First, calculate period and lags. */ period local period "$S_1" local lags=`lags' if `lags'==0 { local lags=`period' } local nl = length("`lags'") /* Allocate working space. */ tempvar work gen double `work' = . /* Store the results calculated so far to protect them from later calculations. */ tempvar est est h `est' /* Durbin-Watson test. */ if `dw' { replace `work'= sum((`res'-`res'[_n-1])^2)/sum(`res'*`res') `if' `in' local DW = `work'[`last'] local x = round(`DW',.001) noi di in gr "Durbin-Watson test: " in ye "`x'" if (`period'>1) { local l = `period' replace `work'= sum((`res'-`res'[_n-`l'])^2)/sum(`res'*`res') `if' `in' local sDW = `work'[`last'] local x = round(`sDW',.001) noi di in gr " seasonal DW test: " in ye "`x'" } } /* Q test. */ if `q' { cap _ac `res' `if' `in', lags(`lags') local i = 1 + 3*`lags' local Q = chiprob(`lags',${S_`i'}) local x = round(`Q',.01) local n = 10 - `nl' noi di _skip(`n') in gr "Q(" in ye "`lags'" in gr ") test: " in ye "`x'" } /* LM, ARCH, and H tests. */ if `arch' | `lm' { conf new v XyZzY local vname "XyZzY" local i = 0 while `i'<`lags' { local i = `i' + 1 _addl `vname' local vname "$S_1" local rhs "`rhs' `vname'" } } if `lm' { /* LM */ rename `res' XyZzY lag `lags' XyZzY reg XyZzY `rhs' `if' `in', nocon local LM = fprob(_result(3),_result(5),_result(6)) drop `rhs' rename XyZzY `res' local x = round(`LM',.01) local n = 9 - `nl' noi di _skip(`n') in gr "LM(" in ye "`lags'" in gr ") test: " in ye "`x'" } if `arch' | `h' { gen double XyZzY = `res'*`res' `if' `in' } if `arch' { /* ARCH */ lag `lags' XyZzY reg XyZzY `rhs' `if' `in' local ARCH = fprob(_result(3),_result(5),_result(6)) drop `rhs' /* local x = round(`ARCH',.01) */ local x : display %5.2f = `ARCH' local n = 7 - `nl' noi di _skip(`n') in gr "ARCH(" in ye "`lags'" in gr ") test: " in ye "`x'" } if `h' { /* H */ replace `work' = sum(XyZzY) `if' `in' local m = int(`N'/3) local h = `m'*(`work'[`last']-`work'[`last'-`m'])/`work'[`first'+`m'-1] local H = chiprob(`m',`h') local x = round(`H',.01) noi di _skip(12) in gr "H test: " in ye "`x'" } cap drop XyZzY /* Test the normality of the residuals. */ if `normal' { tempvar order gen long `order' = _n `in' if (`N' <= 5000) { _sfran `res' `if' `in' local NORM "$S_5" } else { sktest `res' `if' `in' local NORM "$S_4" } sort `order' `in' local x = round(`NORM',.01) noi di _skip(4) in gr "normality test: " in ye "`x'" } /* Add the residual-based diagnostics to the other results. */ est u `est' global S_E_norm "`NORM'" global S_E_DW "`DW'" if ("`sDW'"!="") { global S_E_sDW "`sDW'" } global S_E_Q "`Q'" global S_E_lm "`LM'" global S_E_arch "`ARCH'" global S_E_H "`H'" } /* quietly */ end