*! 1.0.0 Ariel Linden 14Aug2020 // this version has dfbeta() program define metapred, rclass version 16.0 if "`e(cmd)'" != "meta regress" { di as err "You must first run {bf:meta regress} before calling {bf:metapred}" exit } local cmdline = "`e(cmdline)'" local model = "`e(model)'" local method = "`e(method)'" local myopts "RSTAndard RSTUdent DFIts Cooksd Welsch COVratio DFBeta(string)" _pred_se "`myopts'" `0' local typ `s(typ)' local varn `s(varn)' local 0 `"`s(rest)'"' syntax [if][in] [, `myopts' ] marksample touse local oplist "`rstandard' `rstudent' `dfits' `cooksd' `welsch' `covratio' `dfbeta(string)'" opts_exclusive "`oplist'" local type "`rstandard'`rstudent'`dfits'`cooksd'`welsch'`covratio'`dfbeta'" if "`type'" == "" { di as err "one of the available options must be specified" exit 198 } *************** ** rstandard ** *************** else if "`type'" == "rstandard" { _rsta "`typ'" "`varn'" "`touse'" } *************** ** rstudent ** *************** else if "`type'" == "rstudent" { /* restricted to e(sample) */ _rstu "`typ'" "`varn'" "`touse'" "`cmdline'" } // end rstudent *************** ** dfits ** *************** else if "`type'" == "dfits" { /* restricted to e(sample) */ tempvar hh t qui predict double `hh' if `touse', hat qui metapred `t' if `touse', rstudent gen `typ' `varn' = `t'*sqrt(`hh'/(1-`hh')) if `touse' label var `varn' "DFITS" } *************** ** cooksd ** *************** else if "`type'"=="cooksd" { tempvar resid resid_se stdp rsta if "`e(model)'" == "random" { predict double `resid' if `touse', residuals fixedonly se(`resid_se', marginal) } // end random else if "`e(model)'" == "fixed" { predict double `resid' if `touse', residuals se(`resid_se') } // end fixed local k = colsof(e(b)) qui predict `stdp' if `touse', stdp qui metapred `rsta' if `touse', rstand qui gen `typ' `varn'= (`rsta'^2 * (`stdp'/`resid_se')^2)/`k' if `touse' label var `varn' "Cook's D" } *************** ** welsch ** *************** else if "`type'" == "welsch" { /* restricted to e(sample) */ tempvar hh t qui predict double `hh' if `touse', hat qui metapred `t' if `touse', rstudent qui gen `typ' `varn'=(`t'*sqrt(`hh'/(1-`hh')))* /* */ sqrt((e(N)-1)/(1-`hh')) if `touse' label var `varn' "Welsch distance" } *************** ** covratio ** *************** else if "`type'" == "covratio" { /* restricted to e(sample) */ tempvar hh rsta qui predict double `hh' if `touse', hat qui metapred `rsta' if `touse', rstandard local k = colsof(e(b)) local N = e(N) qui gen `typ' `varn' = ((1)/(1-`hh')) * ((`N'-`k'-`rsta'^2) / (`N'-`k'- 1))^`k' label var `varn' "COVRATIO" } *************** ** dfbeta ** *************** if "`dfbeta'"!="" { /* restricted to e(sample) */ DFBeta "`typ'" "`varn'" "`touse'" "`dfbeta'" "`model'" "`method'" } end program define DFBeta /* "`typ'" "`varn'" "`touse'" "`dfbeta'" */ version 16 args type newvar touse var model method _ms_extract_varlist `var' local varlist `"`r(varlist)'"' if `:list sizeof varlist' > 1 { di as err "invalid dfbeta() option;" di as err "too many variables specified" exit 103 } tempname b matrix `b' = e(b) local dim = colsof(`b') local pos = colnumb(`b', "`var'") local rhs : colnames `b' mat drop `b' local USCONS _cons if `:list USCONS in rhs' { local rhs : list rhs - USCONS local --dim } fvrevar `rhs' local rrhs `"`r(varlist)'"' forval i = 1/`dim' { gettoken X rhs : rhs if `i' == `pos' { gettoken y rrhs : rrhs local Y : copy local X } else { gettoken x rrhs : rrhs local xvars `xvars' `x' } } tempvar HAT RSTU lest RES SRES RESULT qui metapred `RSTU' if `touse', rstud qui predict double `HAT' if `touse', hat version 16: _est hold `lest', restore if "`model'" == "random" { meta regress `y' `xvars' if `RSTU'<., nocons random(`method') // we need to manually drop constant from meta regress } else { meta regress `y' `xvars' if `RSTU'<., nocons fixed // we need to manually drop constant from meta regress } qui predict double `RES' if `RSTU'<., res version 16: _est unhold `lest' quietly gen double `SRES'=sum(`RES'^2) qui gen `type' `newvar'=`RSTU'*`RES'/sqrt((1-`HAT')*`SRES'[_N]) label var `newvar' "DFBETA `Y'" end capture program drop _rsta program _rsta, rclass version 16 args type newvar touse qui { if "`e(model)'" == "random" { tempvar resid resid_se predict double `resid' if `touse', residuals fixedonly se(`resid_se', marginal) } // end random else if "`e(model)'" == "fixed" { tempvar resid resid_se predict double `resid' if `touse', residuals se(`resid_se') } // end fixed * gen standardized residuals gen `type' `newvar' = `resid' / `resid_se' label var `newvar' "Standardized residuals" } // end quietly end capture program drop _rstu program _rstu, rclass version 16 args type newvar touse cmdline qui { tempvar sample indho resid rse * account for touse from original meta regress estimation gen `sample' = e(sample) * indicator for hold out study gen `indho' = . count if `sample'==1 local N = r(N) gen double `resid' =. gen double `rse' = . gen double `type' `newvar' = . label var `newvar' "Studentized residuals" // sort so that all touse is at top gsort -`sample' // block to extract options from command line local cmdlne = "`e(cmdline)'" local right = reverse("`cmdlne'") local right = substr("`right'", 1, strpos("`right'", ",") - 1) local right = reverse("`right'") // run LOO loop forval i = 1/`N' { replace `indho' = cond(_n==`i',1,0) `e(cmd)' `e(indepvars)' `indho' if `sample' == 1, `right' * save table of estimates as matrix qui matrix b = r(table) * retrieve estimate and SE for the indicator for the holdout study local est = b[1,colnumb(matrix(b),"`indho'")] local se = b[2,colnumb(matrix(b),"`indho'")] replace `resid' = `est' if `touse' & _n==`i' replace `rse' = `se' if `touse' & _n==`i' replace `type' `newvar' = `est' / `se' if `touse' & _n==`i' } // reset meta regress `cmdline' // resort by trial number sort _meta_id } // end quietly end