*! version 2.3.1 07oct2009 Ben Jann * 1. estadd and helpers * 2. estadd_local * 3. estadd_scalar * 4. estadd_matrix * 5. estadd_mean * 6. estadd_sd * 7. estadd_beta * 8. estadd_coxsnell * 9. estadd_nagelkerke * 10. estadd_ysumm * 11. estadd_summ * 12. estadd_vif * 13. estadd_ebsd * 14. estadd_expb * 15. estadd_pcorr * 16. estadd_lrtest * 17. estadd_brent * 18. estadd_fitstat * 19. estadd_listcoef * 20. estadd_mlogtest * 21. estadd_prchange * 22. estadd_prvalue * 23. estadd_asprvalue * 24. estadd_margins * 99. copy of erepost.ado * 1. program estadd version 8.2 local caller : di _caller() capt _on_colon_parse `0' if !_rc { local 0 `"`s(before)'"' local names `"`s(after)'"' } syntax anything(equalok id="subcommand") [if] [in] [fw aw iw pw] [, * ] if regexm(`"`anything'"',"^r\((.*)\)$") { // check -estadd r(name)- capt confirm scalar `anything' if _rc { capt confirm matrix `anything' if _rc { di as err `"`anything' not found"' exit 111 } else { local anything `"matrix `anything'"' } } else { local anything `"scalar `anything'"' } } gettoken subcommand : anything capt confirm name `subcommand' if _rc { di as err "invalid subcommand" exit 198 } if `"`options'"'!="" local options `", `options'"' if `"`weight'`exp'"'!="" local wgtexp `"[`weight'`exp']"' //expand estimates names and backup current estimates if necessary tempname rcurrent ecurrent capt _return drop `rcurrent' _return hold `rcurrent' capt noisily { local names: list retok names if "`names'"=="" { local names "." local qui } else local qui quietly foreach name of local names { if "`name'"=="." { capt est_expand "`name'" if _rc local enames "`enames'`name' " else local enames "`enames'`r(names)' " } else { est_expand "`name'" //=> error if estimates not found local enames "`enames'`r(names)' " } } local names: list uniq enames if "`names'"=="." local active else { capt est_expand . if _rc local active "." else local active "`r(names)'" if "`active'"=="." | `:list posof "`active'" in names'==0 { local active _est hold `ecurrent', restore estsystem nullok } } } if _rc { _return restore `rcurrent' exit _rc } _return restore `rcurrent', hold // cases: // - if active estimates not stored yet and "`names'"==".": simply execute // estadd_subcmd to active estimates // - else if active estimates not stored yet: backup/restore active estimates // - else if active estimates stored but not in `names': backup/restore active estimates // - else if active estimates stored: no backup but restore at end //loop over estimates names and run subcommand nobreak { foreach m of local names { if "`names'"!="." { if "`m'"=="." _est unhold `ecurrent' else { capt confirm new var _est_`m' // fix e(sample) if _rc qui replace _est_`m' = 0 if _est_`m' >=. _est unhold `m' } } backup_estimates_name capt n break `qui' version `caller': estadd_`anything' `if' `in' `wgtexp' `options' local rc = _rc restore_estimates_name if "`names'"!="." { if "`m'"=="." _est hold `ecurrent', restore estsystem nullok else _est hold `m', estimates varname(_est_`m') } if `rc' continue, break } if "`active'"!="" estimates restore `active', noh } _return restore `rcurrent' if `rc' { if `rc' == 199 di as error "invalid subcommand" exit `rc' } end program define backup_estimates_name, eclass ereturn local _estadd_estimates_name `"`e(_estimates_name)'"' ereturn local _estimates_name "" end program define restore_estimates_name, eclass ereturn local _estimates_name `"`e(_estadd_estimates_name)'"' ereturn local _estadd_estimates_name "" end program confirm_new_ename capture confirm existence `e(`0')' if !_rc { di as err "e(`0') already defined" exit 110 } end program confirm_esample local efun: e(functions) if `:list posof "sample" in efun'==0 { di as err "e(sample) information not available" exit 498 } end program confirm_numvar args var local ts = index("`var'",".") confirm numeric variable `=substr("`var'",`ts'+1,.)' end program define added_macro args name di as txt %25s `"e(`name') : "' `""{res:`e(`name')'}""' end program define added_scalar args name label di as txt %25s `"e(`name') = "' " " as res e(`name') _c if `"`label'"'!="" { di as txt _col(38) `"(`label')"' } else di "" end program define added_matrix args name label capture { local r = rowsof(e(`name')) local c = colsof(e(`name')) } if _rc { tempname tmp mat `tmp' = e(`name') local r = rowsof(`tmp') local c = colsof(`tmp') } di as txt %25s `"e(`name') : "' " " /// as res "`r' x `c'" _c if `"`label'"'=="_rown" { local thelabel: rownames e(`name') local thelabel: list retok thelabel if `r'>1 { local thelabel: subinstr local thelabel " " ", ", all } di as txt _col(38) `"(`thelabel')"' } else if `"`label'"'!="" { di as txt _col(38) `"(`label')"' } else di "" end * 2. * -estadd- subroutine: add local program estadd_loc estadd_local `0' end program estadd_loca estadd_local `0' end program estadd_local, eclass version 8.2 syntax anything(equalok) [, Prefix(name) Replace Quietly ] gettoken name def : anything , parse(" =:") if "`replace'"=="" { confirm_new_ename `prefix'`name' } ereturn local `prefix'`name'`def' di _n as txt "added macro:" added_macro `prefix'`name' end * 3. * -estadd- subroutine: add scalar program estadd_sca estadd_scalar `0' end program estadd_scal estadd_scalar `0' end program estadd_scala estadd_scalar `0' end program estadd_scalar, eclass version 8.2 syntax anything(equalok) [, Prefix(name) Replace Quietly ] if regexm("`anything'","^r\((.*)\)$") { // estadd scalar r(name) local name = regexs(1) capt confirm name `name' confirm scalar `anything' if _rc error 198 local equ "`anything'" } else { local isname 0 gettoken name equ0: anything, parse(" =") capt confirm name `name' if _rc error 198 else if `"`equ0'"'=="" { // estadd scalar name local isname 1 local equ "scalar(`name')" } else { // estadd scalar name [=] exp gettoken trash equ : equ0, parse(" =") if `"`trash'"'!="=" { local equ `"`equ0'"' } } } if "`replace'"=="" { confirm_new_ename `prefix'`name' } ereturn scalar `prefix'`name' = `equ' di _n as txt "added scalar:" added_scalar `prefix'`name' end * 4. * -estadd- subroutine: add matrix program estadd_mat estadd_matrix `0' end program estadd_matr estadd_matrix `0' end program estadd_matri estadd_matrix `0' end program estadd_matrix, eclass version 8.2 syntax anything(equalok) [, Prefix(name) Replace Quietly ] if regexm("`anything'","^r\((.*)\)$") { // estadd matrix r(name) local name = regexs(1) capt confirm name `name' if _rc error 198 confirm matrix `anything' local equ "`anything'" } else { local isname 0 gettoken name equ0: anything, parse(" =") capt confirm name `name' if _rc error 198 else if `"`equ0'"'=="" { // estadd matrix name local isname 1 local equ "`name'" } else { // estadd matrix name [=] exp gettoken trash equ : equ0, parse(" =") if `"`trash'"'!="=" { local equ `"`equ0'"' } } } if "`replace'"=="" { confirm_new_ename `prefix'`name' } tempname M mat `M' = `equ' ereturn matrix `prefix'`name' = `M' di _n as txt "added matrix:" added_matrix `prefix'`name' end * 5. * -estadd- subroutine: means of regressors program define estadd_mean, eclass version 8.2 syntax [, Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //check e()-names if "`replace'"=="" confirm_new_ename `prefix'mean //use aweights with -summarize- local wtype `e(wtype)' if "`wtype'"=="pweight" local wtype aweight //subpop? local subpop "`e(subpop)'" if "`subpop'"=="" local subpop 1 //copy coefficients matrix and determine varnames tempname results mat `results' = e(b) local vars: colnames `results' //loop over variables: calculate -mean- local j 0 foreach var of local vars { local ++j capture confirm_numvar `var' if _rc mat `results'[1,`j'] = .z else { capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop', meanonly mat `results'[1,`j'] = cond(_rc,.,r(mean)) } } //return the results ereturn matrix `prefix'mean = `results' di _n as txt "added matrix:" added_matrix `prefix'mean end * 6. * -estadd- subroutine: standard deviations of regressors program define estadd_sd, eclass version 8.2 syntax [, noBinary Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //check e()-names if "`replace'"=="" confirm_new_ename `prefix'sd //use aweights with -summarize- local wtype `e(wtype)' if "`wtype'"=="pweight" local wtype aweight //subpop? local subpop "`e(subpop)'" if "`subpop'"=="" local subpop 1 //copy coefficients matrix and determine varnames tempname results mat `results' = e(b) local vars: colnames `results' //loop over variables: calculate -mean- local j 0 foreach var of local vars { local ++j capture confirm_numvar `var' if _rc mat `results'[1,`j'] = .z else { capture assert `var'==0 | `var'==1 if e(sample) & `subpop' if _rc | "`binary'"=="" { capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop' mat `results'[1,`j'] = cond(_rc,.,r(sd)) } else mat `results'[1,`j'] = .z } } //return the results ereturn matrix `prefix'sd = `results' di _n as txt "added matrix:" added_matrix `prefix'sd end * 7. * -estadd- subroutine: standardized coefficients program define estadd_beta, eclass version 8.2 syntax [, Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //check e()-names if "`replace'"=="" confirm_new_ename `prefix'beta //use aweights with -summarize- local wtype `e(wtype)' if "`wtype'"=="pweight" local wtype aweight //subpop? local subpop "`e(subpop)'" if "`subpop'"=="" local subpop 1 //copy coefficients matrix and determine varnames tempname results sddep mat `results' = e(b) local vars: colnames `results' local eqs: coleq `results', q local depv "`e(depvar)'" //loop over variables: calculate -beta- local j 0 local lastdepvar foreach var of local vars { local depvar: word `++j' of `eqs' if "`depvar'"=="_" local depvar "`depv'" capture confirm_numvar `depvar' if _rc mat `results'[1,`j'] = .z else { if "`depvar'"!="`lastdepvar'" { capt su `depvar' [`wtype'`e(wexp)'] if e(sample) & `subpop' scalar `sddep' = cond(_rc,.,r(sd)) } capture confirm_numvar `var' if _rc mat `results'[1,`j'] = .z else { capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop' mat `results'[1,`j'] = cond(_rc,.,`results'[1,`j'] * r(sd) / `sddep') } } local lastdepvar "`depvar'" } //return the results ereturn matrix `prefix'beta = `results' di _n as txt "added matrix:" added_matrix `prefix'beta end * 8. * -estadd- subroutine: Cox & Snell Pseudo R-Squared program define estadd_coxsnell, eclass version 8.2 syntax [, Prefix(name) Replace Quietly ] //check e()-names if "`replace'"=="" confirm_new_ename `prefix'coxsnell //compute statistic tempname results scalar `results' = 1 - exp((e(ll_0)-e(ll))*2/e(N)) // = 1 - exp(e(ll_0)-e(ll))^(2/e(N)) //return the results *di as txt "Cox & Snell Pseudo R2 = " as res `results' ereturn scalar `prefix'coxsnell = `results' di _n as txt "added scalar:" added_scalar `prefix'coxsnell end * 9. * -estadd- subroutine: Nagelkerke Pseudo R-Squared program define estadd_nagelkerke, eclass version 8.2 syntax [, Prefix(name) Replace Quietly ] //check e()-names if "`replace'"=="" confirm_new_ename `prefix'nagelkerke //compute statistic tempname results scalar `results' = (1 - exp((e(ll_0)-e(ll))*2/e(N))) / (1 - exp(e(ll_0)*2/e(N))) // = (1 - exp(e(ll_0)-e(ll))^(2/e(N))) / (1 - exp(e(ll_0))^(2/e(N))) //return the results *di as txt "Nagelkerke Pseudo R2 = " as res `results' ereturn scalar `prefix'nagelkerke = `results' di _n as txt "added scalar:" added_scalar `prefix'nagelkerke end * 10. * -estadd- subroutine: summary statistics for dependent variable program define estadd_ysumm, eclass version 8.2 syntax [, MEan SUm MIn MAx RAnge sd Var cv SEMean SKewness /// Kurtosis MEDian p1 p5 p10 p25 p50 p75 p90 p95 p99 iqr q all /// Prefix(passthru) Replace Quietly ] //check availability of e(sample) confirm_esample //default prefix if `"`prefix'"'=="" local prefix y else { local 0 ", `prefix'" syntax [, prefix(name) ] } //use aweights with -summarize- local wtype `e(wtype)' if "`wtype'"=="pweight" local wtype aweight //subpop? local subpop "`e(subpop)'" if "`subpop'"=="" local subpop 1 //determine list of stats tempname results local Stats p99 p95 p90 p75 p50 p25 p10 p5 p1 kurtosis /// skewness var sd max min sum mean if "`all'"!="" { local stats `Stats' local range range local cv cv local semean semean local iqr iqr local sumtype detail } else { if "`q'"!="" { local p25 p25 local p50 p50 local p75 p75 } if "`median'"!="" local p50 p50 foreach stat of local Stats { if "``stat''"!="" { local stats: list stats | stat } } if "`stats'"=="" & "`range'"=="" & "`cv'"=="" & /// "`semean'"=="" & "`iqr'"=="" local stats sd max min mean local sumtype sum mean min max if "`:list stats - sumtype'"=="" & "`cv'"=="" & /// "`semean'"=="" & "`iqr'"=="" local sumtype meanonly else { local sumtype `sumtype' Var sd if "`:list stats - sumtype'"=="" & "`iqr'"=="" local sumtype else local sumtype detail } } local Stats: subinstr local stats "var" "Var" local nstats: word count `iqr' `semean' `cv' `range' `stats' if "`replace'"=="" { foreach stat in `iqr' `semean' `cv' `range' `stats' { confirm_new_ename `prefix'`=lower("`stat'")' } } //calculate stats local var: word 1 of `e(depvar)' mat `results' = J(`nstats',1,.z) qui su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop', `sumtype' local i 0 if "`iqr'"!="" { mat `results'[`++i',1] = r(p75) - r(p25) } if "`semean'"!="" { mat `results'[`++i',1] = r(sd) / sqrt(r(N)) } if "`cv'"!="" { mat `results'[`++i',1] = r(sd) / r(mean) } if "`range'"!="" { mat `results'[`++i',1] = r(max) - r(min) } foreach stat of local Stats { mat `results'[`++i',1] = r(`stat') } //return the results local i 0 di as txt _n "added scalars:" foreach stat in `iqr' `semean' `cv' `range' `stats' { local sname = lower("`stat'") ereturn scalar `prefix'`sname' = `results'[`++i',1] added_scalar `prefix'`sname' } end * 11. * -estadd- subroutine: various summary statistics program define estadd_summ, eclass version 8.2 syntax [, MEan SUm MIn MAx RAnge sd Var cv SEMean SKewness /// Kurtosis MEDian p1 p5 p10 p25 p50 p75 p90 p95 p99 iqr q all /// Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //use aweights with -summarize- local wtype `e(wtype)' if "`wtype'"=="pweight" local wtype aweight //subpop? local subpop "`e(subpop)'" if "`subpop'"=="" local subpop 1 //determine list of stats tempname results results2 local Stats p99 p95 p90 p75 p50 p25 p10 p5 p1 kurtosis /// skewness var sd max min sum mean if "`all'"!="" { local stats `Stats' local range range local cv cv local semean semean local iqr iqr local sumtype detail } else { if "`q'"!="" { local p25 p25 local p50 p50 local p75 p75 } if "`median'"!="" local p50 p50 foreach stat of local Stats { if "``stat''"!="" { local stats: list stats | stat } } if "`stats'"=="" & "`range'"=="" & "`cv'"=="" & /// "`semean'"=="" & "`iqr'"=="" local stats sd max min mean local sumtype sum mean min max if "`:list stats - sumtype'"=="" & "`cv'"=="" & /// "`semean'"=="" & "`iqr'"=="" local sumtype meanonly else { local sumtype `sumtype' Var sd if "`:list stats - sumtype'"=="" & "`iqr'"=="" local sumtype else local sumtype detail } } local Stats: subinstr local stats "var" "Var" local nstats: word count `iqr' `semean' `cv' `range' `stats' if "`replace'"=="" { foreach stat in `iqr' `semean' `cv' `range' `stats' { confirm_new_ename `prefix'`=lower("`stat'")' } } //copy coefficients matrix and determine varnames mat `results' = e(b) local vars: colnames `results' if `nstats'>1 { mat `results' = `results' \ J(`nstats'-1,colsof(`results'),.z) } //loop over variables: calculate stats local j 0 foreach var of local vars { local ++j capture confirm_numvar `var' if _rc mat `results'[1,`j'] = .z else { capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop', `sumtype' local i 0 if "`iqr'"!="" { mat `results'[`++i',`j'] = cond(_rc,.,r(p75) - r(p25)) } if "`semean'"!="" { mat `results'[`++i',`j'] = cond(_rc,.,r(sd) / sqrt(r(N))) } if "`cv'"!="" { mat `results'[`++i',`j'] = cond(_rc,.,r(sd) / r(mean)) } if "`range'"!="" { mat `results'[`++i',`j'] = cond(_rc,.,r(max) - r(min)) } foreach stat of local Stats { mat `results'[`++i',`j'] = cond(_rc,.,r(`stat')) } } } //return the results local i 0 di as txt _n "added matrices:" foreach stat in `iqr' `semean' `cv' `range' `stats' { local sname = lower("`stat'") mat `results2' = `results'[`++i',1...] ereturn matrix `prefix'`sname' = `results2' added_matrix `prefix'`sname' } end * 12. * -estadd- subroutine: variance inflation factors program define estadd_vif, eclass version 8.2 local caller : di _caller() syntax [, TOLerance SQRvif Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //check e()-names if "`replace'"=="" { confirm_new_ename `prefix'vif if "`tolerance'"!="" confirm_new_ename `prefix'tolerance if "`sqrvif'"!="" confirm_new_ename `prefix'sqrvif } //copy coefficients matrix and set to .z tempname results results2 results3 matrix `results' = e(b) forv j = 1/`=colsof(`results')' { mat `results'[1,`j'] = .z } if "`tolerance'"!="" mat `results2' = `results' if "`sqrvif'"!="" mat `results3' = `results' //compute VIF and add to results vector capt n `quietly' version `caller': vif if _rc { if _rc == 301 di as err "-estadd:vif- can only be used after -regress-" exit _rc } local i 0 local name "`r(name_`++i')'" while "`name'"!="" { local j = colnumb(`results',"`name'") if `j'<. { matrix `results'[1,`j'] = r(vif_`i') if "`tolerance'"!="" matrix `results2'[1,`j'] = 1 / r(vif_`i') if "`sqrvif'"!="" matrix `results3'[1,`j'] = sqrt( r(vif_`i') ) } local name "`r(name_`++i')'" } //return the results if "`sqrvif'"!="" | "`tolerance'"!="" di as txt _n "added matrices:" else di as txt _n "added matrix:" if "`sqrvif'"!="" { ereturn matrix `prefix'sqrvif = `results3' added_matrix `prefix'sqrvif } if "`tolerance'"!="" { ereturn matrix `prefix'tolerance = `results2' added_matrix `prefix'tolerance } ereturn matrix `prefix'vif = `results' added_matrix `prefix'vif end * 13. * -estadd- subroutine: standardized factor change coefficients program define estadd_ebsd, eclass version 8.2 syntax [, Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //check e()-names if "`replace'"=="" confirm_new_ename `prefix'ebsd //use aweights with -summarize- local wtype `e(wtype)' if "`wtype'"=="pweight" local wtype aweight //subpop? local subpop "`e(subpop)'" if "`subpop'"=="" local subpop 1 //copy coefficients matrix and determine varnames tempname results mat `results' = e(b) local vars: colnames `results' //loop over variables: calculate -mean- local j 0 foreach var of local vars { local ++j capture confirm_numvar `var' if _rc mat `results'[1,`j'] = .z else { capt su `var' [`wtype'`e(wexp)'] if e(sample) & `subpop' mat `results'[1,`j'] = cond(_rc,.,exp( `results'[1,`j'] * r(sd))) } } //return the results ereturn matrix `prefix'ebsd = `results' di _n as txt "added matrix:" added_matrix `prefix'ebsd end * 14. * -estadd- subroutine: exponentiated coefficients program define estadd_expb, eclass version 8.2 syntax [, noCONStant Prefix(name) Replace Quietly ] //check e()-names if "`replace'"=="" confirm_new_ename `prefix'expb //copy coefficients matrix and determine names of coefficients tempname results mat `results' = e(b) local coefs: colnames `results' //loop over coefficients local j 0 foreach coef of local coefs { local ++j if `"`constant'"'!="" & `"`coef'"'=="_cons" { mat `results'[1,`j'] = .z } else { mat `results'[1,`j'] = exp(`results'[1,`j']) } } //return the results ereturn matrix `prefix'expb = `results' di _n as txt "added matrix:" added_matrix `prefix'expb end * 15. * -estadd- subroutine: partial and semi-partial correlations program define estadd_pcorr, eclass version 8.2 syntax [, semi Prefix(name) Replace Quietly ] //check availability of e(sample) confirm_esample //check e()-names if "`replace'"=="" { if "`semi'"!="" confirm_new_ename `prefix'spcorr confirm_new_ename `prefix'pcorr } //copy coefficients matrix and set to .z tempname results results2 matrix `results' = e(b) forv j = 1/`=colsof(`results')' { mat `results'[1,`j'] = .z } local eqs: coleq `results', quoted local eq: word 1 of `eqs' mat `results2' = `results'[1,"`eq':"] local vars: colnames `results2' foreach var of local vars { capt confirm numeric var `var' if !_rc local temp "`temp'`var' " } local vars "`temp'" if "`semi'"!="" mat `results2' = `results' else { mat drop `results2' local results2 } local depv: word 1 of `e(depvar)' //compute statistics and add to results vector local wtype `e(wtype)' if inlist("`wtype'","pweight","iweight") local wtype aweight _estadd_pcorr_compute `depv' `vars' [`wtype'`e(wexp)'] if e(sample), /// eq(`eq') results(`results') results2(`results2') //return the results if "`semi'"!="" { di as txt _n "added matrices:" ereturn matrix `prefix'spcorr = `results2' added_matrix `prefix'spcorr } else di as txt _n "added matrix:" ereturn matrix `prefix'pcorr = `results' added_matrix `prefix'pcorr end program define _estadd_pcorr_compute // based on pcorr.ado by StataCorp // and pcorr2.ado by Richard Williams syntax varlist(min=1) [aw fw] [if], eq(str) results(str) [ results2(str) ] marksample touse tempname hcurrent _est hold `hcurrent', restore quietly reg `varlist' [`weight'`exp'] if `touse' if (e(N)==0 | e(N)>=.) error 2000 local NmK = e(df_r) local R2 = e(r2) gettoken depv varlist: varlist foreach var of local varlist { quietly test `var' if r(F)<. { local s "1" if _b[`var']<0 local s "-1" local c = colnumb(`results',"`eq':`var'") mat `results'[1,`c'] = `s' * sqrt(r(F)/(r(F)+`NmK')) if "`results2'"!="" { mat `results2'[1,`c'] = `s' * sqrt(r(F)*((1-`R2')/`NmK')) } } } end * 16. * -estadd- subroutine: Likelihood-ratio test program define estadd_lrtest, eclass version 8.2 local caller : di _caller() syntax anything(id="model") [, Name(name) Prefix(name) Replace Quietly * ] if "`name'"=="" local name lrtest_ //check e()-names if "`replace'"=="" { confirm_new_ename `prefix'`name'p confirm_new_ename `prefix'`name'chi2 confirm_new_ename `prefix'`name'df } //compute statistics `quietly' version `caller': lrtest `anything', `options' //return the results ereturn scalar `prefix'`name'p = r(p) ereturn scalar `prefix'`name'chi2 = r(chi2) ereturn scalar `prefix'`name'df = r(df) di _n as txt "added scalars:" added_scalar `prefix'`name'p added_scalar `prefix'`name'chi2 added_scalar `prefix'`name'df end * 17. * -estadd- subroutine: support for -brant- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_brant, eclass version 8.2 local caller : di _caller() syntax [ , Prefix(name) Replace Quietly * ] capt findfile brant.ado if _rc { di as error "fitstat.ado from the -spost9_ado- package by Long and Freese required" di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"' error 499 } // check names if "`replace'"=="" { foreach name in brant_chi2 brant_df brant_p brant { confirm_new_ename `prefix'`name' } } // compute and return the results `quietly' version `caller': brant, `options' di as txt _n "added scalars:" foreach stat in chi2 df p { ereturn scalar `prefix'brant_`stat' = r(`stat') added_scalar `prefix'brant_`stat' } tempname mat matrix `mat' = r(ivtests) matrix `mat' = `mat'' ereturn matrix `prefix'brant = `mat' di as txt _n "added matrix:" added_matrix `prefix'brant _rown end * 18. * -estadd- subroutine: support for -fitstat- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_fitstat, eclass version 8.2 local caller : di _caller() syntax [ , Prefix(name) Replace Quietly Bic * ] capt findfile fitstat.ado if _rc { di as error "fitstat.ado from the -spost9_ado- package by Long and Freese required" di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"' error 499 } `quietly' version `caller': fitstat, `bic' `options' local stats: r(scalars) local allstats /// dev dev_df lrx2 lrx2_df lrx2_p r2_adj r2_mf r2_mfadj r2_ml /// r2_cu r2_mz r2_ef v_ystar v_error r2_ct r2_ctadj aic aic_n /// bic bic_p statabic stataaic n_rhs n_parm local stats: list allstats & stats if "`bic'"!="" { local bic aic aic_n bic bic_p statabic stataaic local stats: list bic & stats } // check names if "`replace'"=="" { foreach stat of local stats { if inlist("`stat'", "bic", "aic") local rname `stat'0 else local rname `stat' confirm_new_ename `prefix'`rname' } } // return the results di as txt _n "added scalars:" foreach stat of local stats { if inlist("`stat'", "bic", "aic") local rname `stat'0 else local rname `stat' ereturn scalar `prefix'`rname' = r(`stat') added_scalar `prefix'`rname' } end * 19. * -estadd- subroutine: support for -listcoef- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_listcoef, eclass version 8.2 local caller : di _caller() syntax [anything] [ , Prefix(name) Replace Quietly /// nosd gt lt ADJacent Matrix EXpand * ] // handle some options and look for e(sample) if `"`matrix'"'!="" { local matrix matrix } if `"`e(cmd)'"'=="slogit" & "`expand'"!="" { di as err "-expand- option not supported" exit 198 } confirm_esample // set some constants local listcoef_matrices "xs ys std fact facts pct pcts" if "`sd'"=="" local listcoef_matrices "`listcoef_matrices' sdx" // run listcoef capt findfile listcoef.ado if _rc { di as error "-listcoef- from the -spost9_ado- package by Long and Freese required" di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"' error 499 } `quietly' version `caller': listcoef `anything' , matrix `gt' `lt' `adjacent' `options' // check existing e()'s if "`replace'"=="" { confirm_new_ename `prefix'pvalue foreach matrix of local listcoef_matrices { _estadd_listcoef_ChkEName b_`matrix', prefix(`prefix') } } // grab r()-results and post in e() di as txt _n "added matrices:" if inlist(`"`e(cmd)'"',"mlogit","mprobit") { _estadd_listcoef_AddResToNomModl `listcoef_matrices', prefix(`prefix') `gt' `lt' `adjacent' } else { foreach matrix of local listcoef_matrices { _estadd_listcoef_AddMatToE `matrix', prefix(`prefix') } } end program define _estadd_listcoef_ChkEName syntax name [, prefix(str) ] capt confirm matrix r(`namelist') if _rc exit confirm_new_ename `prefix'`namelist' end program define _estadd_listcoef_AddMatToE, eclass syntax name [, prefix(str) ] capt confirm matrix r(b_`namelist') if _rc exit tempname tmp matrix `tmp' = r(b_`namelist') capt confirm matrix r(b2_`namelist') if _rc==0 { local eqnames: coleq e(b), quoted local eqnames: list uniq eqnames local eqname: word 1 of `eqnames' mat coleq `tmp' = `"`eqname'"' tempname tmp2 matrix `tmp2' = r(b2_`namelist') local eqname: word 2 of `eqnames' mat coleq `tmp2' = `"`eqname'"' mat `tmp' = `tmp' , `tmp2' mat drop `tmp2' } ereturn matrix `prefix'b_`namelist' = `tmp' added_matrix `prefix'b_`namelist' _rown end program define _estadd_listcoef_AddResToNomModl, eclass syntax anything(name=listcoef_matrices) [, prefix(str) gt lt ADJacent ] if "`lt'"=="" & "`gt'"=="" { local lt lt local gt gt } local adjacent = "`adjacent'"!="" local lt = "`lt'"!="" local gt = "`gt'"!="" // outcomes and labels tempname outcomes if `"`e(cmd)'"'=="mlogit" { if c(stata_version) < 9 local type cat else local type out mat `outcomes' = e(`type') local noutcomes = colsof(`outcomes') local eqnames `"`e(eqnames)'"' if (`:list sizeof eqnames'<`noutcomes') { local ibase = e(ibase`type') } else local ibase 0 forv i = 1/`noutcomes' { if `i'==`ibase' { local outcomelab`i' `"`e(baselab)'"' } else { gettoken eq eqnames : eqnames local outcomelab`i' `"`eq'"' } if `"`outcomelab`i''"'=="" { local outcomelab`i': di `outcomes'[1,`i'] } } } else if `"`e(cmd)'"'=="mprobit" { mat `outcomes' = e(outcomes)' local noutcomes = colsof(`outcomes') forv i = 1/`noutcomes' { local outcomelab`i' `"`e(out`i')'"' } } else { di as err `"`e(cmd)' not supported" exit 499 } // collect vectors tempname stats mat `stats' = r(b) \ r(b_z) \ r(b_z) \ r(b_p) forv i = 1/`=colsof(`stats')' { mat `stats'[2,`i'] = `stats'[1,`i'] / `stats'[3,`i'] } mat rown `stats' = "b" "se" "z" "P>|z|" local enames "b_raw b_se b_z b_p" foreach matrix of local listcoef_matrices { capt confirm matrix r(b_`matrix') if _rc continue mat `stats' = `stats' \ r(b_`matrix') local enames `"`enames' b_`matrix'"' } // select/reorder contrasts of interest local contrast "r(contrast)" local ncontrast = colsof(`contrast') tempname stats0 temp matrix rename `stats' `stats0' forv i = 1/`noutcomes' { local out1 = `outcomes'[1, `i'] local j 0 forv j = 1/`noutcomes' { local out2 = `outcomes'[1, `j'] if `out1'==`out2' continue if `adjacent' & abs(`i'-`j')>1 continue if `lt'==0 & `out1'<`out2' continue if `gt'==0 & `out1'>`out2' continue forv l = 1/`ncontrast' { if el(`contrast',1,`l')!=`out1' continue if el(`contrast',2,`l')!=`out2' continue mat `temp' = `stats0'[1..., `l'] mat coleq `temp' = `"`outcomelab`i''-`outcomelab`j'"' mat `stats' = nullmat(`stats'), `temp' } } } capt mat drop `stats0' // post rows to e() local i 0 foreach ename of local enames { local ++i mat `temp' = `stats'[`i', 1...] ereturn matrix `prefix'`ename' = `temp' added_matrix `prefix'`ename' _rown } end * 20. * -estadd- subroutine: support for -mlogtest- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_mlogtest, eclass version 8.2 local caller : di _caller() syntax [anything] [ , Prefix(name) Replace Quietly set(passthru) * ] `quietly' version `caller': mlogtest `anything' , `set' `options' local rmat: r(matrices) // check names if `"`replace'"'=="" { foreach m in combine lrcomb { if `:list m in rmat'==0 continue forv r = 1/`=rowsof(r(`m'))' { local cat1 = el(r(`m'),`r',1) local cat2 = el(r(`m'),`r',2) confirm_new_ename `prefix'`m'_`cat1'_`cat2'_chi2 confirm_new_ename `prefix'`m'_`cat1'_`cat2'_df confirm_new_ename `prefix'`m'_`cat1'_`cat2'_p } } foreach m in hausman suest smhsiao { if `:list m in rmat'==0 continue forv r = 1/`=rowsof(r(`m'))' { local cat = el(r(`m'),`r',1) confirm_new_ename `prefix'`m'_`cat'_chi2 confirm_new_ename `prefix'`m'_`cat'_df confirm_new_ename `prefix'`m'_`cat'_p } } if `"`set'"'!="" { foreach m in wald lrtest { if `:list m in rmat'==0 continue local i 0 local r = rownumb(r(`m'),"set_`++i'") while(`r'<.) { confirm_new_ename `prefix'`m'_set`i'_chi2 confirm_new_ename `prefix'`m'_set`i'_df confirm_new_ename `prefix'`m'_set`i'_p local r = rownumb(r(`m'),"set_`++i'") } } } foreach m in wald lrtest { if `:list m in rmat'==0 continue local r . if `"`set'"'!="" local r = rownumb(r(`m'),"set_1")-1 if `r'<1 continue confirm_new_ename `prefix'`m' } } local di_added_scalars `"di _n as txt "added scalars:"' // combine foreach m in combine lrcomb { if `:list m in rmat'==0 continue `di_added_scalars' local di_added_scalars forv r = 1/`=rowsof(r(`m'))' { local cat1 = el(r(`m'),`r',1) local cat2 = el(r(`m'),`r',2) eret scalar `prefix'`m'_`cat1'_`cat2'_chi2 = el(r(`m'),`r',3) added_scalar `prefix'`m'_`cat1'_`cat2'_chi2 eret scalar `prefix'`m'_`cat1'_`cat2'_df = el(r(`m'),`r',4) added_scalar `prefix'`m'_`cat1'_`cat2'_df eret scalar `prefix'`m'_`cat1'_`cat2'_p = el(r(`m'),`r',5) added_scalar `prefix'`m'_`cat1'_`cat2'_p } } // iia foreach m in hausman suest smhsiao { if `:list m in rmat'==0 continue `di_added_scalars' local di_added_scalars if "`m'"=="smhsiao" local skip 2 else local skip 0 forv r = 1/`=rowsof(r(`m'))' { local cat = el(r(`m'),`r',1) eret scalar `prefix'`m'_`cat'_chi2 = el(r(`m'),`r',2+`skip') added_scalar `prefix'`m'_`cat'_chi2 eret scalar `prefix'`m'_`cat'_df = el(r(`m'),`r',3+`skip') added_scalar `prefix'`m'_`cat'_df eret scalar `prefix'`m'_`cat'_p = el(r(`m'),`r',4+`skip') added_scalar `prefix'`m'_`cat'_p } } // wald/lrtest tempname tmp if `"`set'"'!="" { foreach m in wald lrtest { if `:list m in rmat'==0 continue local i 0 local r = rownumb(r(`m'),"set_`++i'") if `r'>=. continue `di_added_scalars' local di_added_scalars while(`r'<.) { eret scalar `prefix'`m'_set`i'_chi2 = el(r(`m'),`r',1) added_scalar `prefix'`m'_set`i'_chi2 eret scalar `prefix'`m'_set`i'_df = el(r(`m'),`r',2) added_scalar `prefix'`m'_set`i'_df eret scalar `prefix'`m'_set`i'_p = el(r(`m'),`r',3) added_scalar `prefix'`m'_set`i'_p local r = rownumb(r(`m'),"set_`++i'") } } } local di_added_matrices `"di _n as txt "added matrices:"' foreach m in wald lrtest { if `:list m in rmat'==0 continue local r . if `"`set'"'!="" local r = rownumb(r(`m'),"set_1")-1 if `r'<1 continue `di_added_matrices' local di_added_matrices mat `tmp' = r(`m') mat `tmp' = `tmp'[1..`r',1...]' eret mat `prefix'`m' = `tmp' added_matrix `prefix'`m' _rown } end * 21. * -estadd- subroutine: support for -prchange- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_prchange version 8.2 local caller : di _caller() syntax [anything] [if] [in] [ , Prefix(name) Replace Quietly /// PAttern(str) Binary(str) Continuous(str) NOAvg Avg split SPLIT2(name) /// adapt /// old syntax; now works as synonym for noavg Outcome(passthru) Fromto noBAse * ] // handle some options if `"`split2'"'!="" local split split if "`split'"!="" & `"`outcome'"'!="" { di as err "split and outcome() not both allowed" exit 198 } if "`split'"!="" & `"`avg'`noavg'"'!="" { di as err "split and avg not both allowed" exit 198 } if "`avg'"!="" & `"`outcome'"'!="" { di as err "avg and outcome not both allowed" exit 198 } if "`avg'"!="" & "`noavg'"!="" { di as err "avg and noavg not both allowed" exit 198 } if `"`adapt'"'!="" local noavg noavg if `:list sizeof binary'>1 | `:list sizeof continuous'>1 error 198 estadd_prchange_ExpandType binary `"`binary'"' estadd_prchange_ExpandType continuous `"`continuous'"' if `"`binary'"'=="" local binary 2 if `"`continuous'"'=="" local continuous 4 if `"`pattern'"'!="" { estadd_prchange_ExpandType pattern `"`pattern'"' } // check e(sample) confirm_esample // run prchange capt findfile prchange.ado if _rc { di as error "-prchange- from the -spost9_ado- package by Long and Freese required" di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"' error 499 } `quietly' version `caller': prchange `anything' `if' `in', `base' `outcome' `fromto' `options' // determine type of model (ordinal: nomord = 1; nominal: nomord = 2) local nomord = (r(modeltype)=="typical nomord") if inlist(`"`e(cmd)'"',"mlogit","mprobit") local nomord = 2 if "`avg'`noavg'"!="" { if `nomord'==0 { di as err "avg not allowed with this model" exit 198 } } if !`nomord' & "`split'"!="" { di as err "split not allowed with this model" exit 198 } // determine outcome number (in prchange-returns) if `"`outcome'"'!="" { if `nomord' { forv i = 1/`=colsof(r(catval))' { if el(r(catval), 1, `i') == r(outcome) { local outcomenum `i' continue, break } } if "`outcomenum'"=="" { // should never happen di as err `"outcome `outcome' not found"' exit 499 } } else { local outcomenum = colnumb(r(predval), `"`r(outcome)'"') } } // check names if "`replace'"=="" { if `"`outcome'"'!="" | "`split'"!="" | `nomord'==0 { confirm_new_ename `prefix'predval if `"`outcome'"'!="" | "`split'"!="" { confirm_new_ename `prefix'outcome } } else { forv i = 1/`=colsof(r(catval))' { local theoutcome: di el(r(catval),1,`i') confirm_new_ename `prefix'predval`theoutcome' } } confirm_new_ename `prefix'delta confirm_new_ename `prefix'centered confirm_new_ename `prefix'dc if "`fromto'"!="" { confirm_new_ename `prefix'dcfrom confirm_new_ename `prefix'dcto } if "`nobase'"=="" { confirm_new_ename `prefix'X } } // grab r()-results and post in e() if "`split'"!="" { if `"`split2'"'=="" { local split2 `"`e(_estadd_estimates_name)'"' if `"`split2'"'=="" { local split2 `"`e(cmd)'"' } local split2 `"`split2'_"' } _estadd_prchange_StoreEachOutc `split2' , nomord(`nomord') /// pattern(`pattern') binary(`binary') continuous(`continuous') /// `base' `fromto' prefix(`prefix') } else { _estadd_prchange_AddStuffToE, nomord(`nomord') outcome(`outcomenum') /// pattern(`pattern') binary(`binary') continuous(`continuous') /// `avg' `noavg' `base' `fromto' prefix(`prefix') } end program estadd_prchange_ExpandType args name list foreach l of local list { local w = length(`"`l'"') if `"`l'"'==substr("minmax",1,max(2,`w')) local type 1 else if `"`l'"'==substr("01",1,max(1,`w')) local type 2 else if `"`l'"'==substr("delta",1,max(1,`w')) local type 3 else if `"`l'"'==substr("sd",1,max(1,`w')) local type 4 else if `"`l'"'==substr("margefct",1,max(1,`w')) local type 5 else { di as err `"'`l'' not allowed"' exit 198 } local newlist `newlist' `type' } c_local `name' `newlist' end program define _estadd_prchange_AddStuffToE, eclass // input add // ========================= ======================================== // outcome() nomord opt change changenm change# predval outcome // no 0 - x last // yes 0 - x x x // no 1/2 - x all all // yes 1/2 - x x x // no 1/2 avg x all // no 1/2 noavg all all // nobase=="" => add X, SD, Min, Max // all models => add centered, delta syntax , nomord(str) [ pattern(passthru) binary(passthru) continuous(passthru) /// outcome(str) NOAVG avg nobase fromto prefix(str) ] // // prepare predval and determine value of outcome if `"`outcome'"'!="" { tempname predv mat `predv' = r(predval) mat `predv' = `predv'[1...,`outcome'] if `nomord' { local theoutcome: di el(r(catval),1,`outcome') } else { local theoutcome: colnames `predv' } } // add scalars di _n as txt "added scalars:" // - predval and outcome local cpredval = colsof(r(predval)) if `"`outcome'"'!="" { ereturn scalar `prefix'predval = `predv'[1,1] added_scalar `prefix'predval `"`lab_predval'"' ereturn scalar `prefix'outcome = `theoutcome' added_scalar `prefix'outcome } else if `nomord' { // add all forv i=1/`cpredval' { local theoutcome: di el(r(catval),1,`i') ereturn scalar `prefix'predval`theoutcome' = el(r(predval),1,`i') added_scalar `prefix'predval`theoutcome' } } else { // add last ereturn scalar `prefix'predval = el(r(predval),1,`cpredval') added_scalar `prefix'predval } // - delta and centered ereturn scalar `prefix'delta = r(delta) added_scalar `prefix'delta ereturn scalar `prefix'centered = r(centered) added_scalar `prefix'centered // add matrices di _n as txt "added matrices:" if `nomord'==0 { if r(modeltype)=="twoeq count" & "`test'"=="" { local eq: coleq e(b) local eq: word 1 of `eq' } _estadd_prchange_PostMat r(change), prefix(`prefix') /// name(dc) `pattern' `binary' `continuous' `fromto' eq(`eq') } else { if `"`outcome'"'=="" { if "`avg'"!="" local nomordmat "r(changemn)" else { tempname nomordmat _estadd_prchange_GatherNomChMat `nomordmat' `noavg' } _estadd_prchange_PostMat `nomordmat', prefix(`prefix') /// name(dc) `pattern' `binary' `continuous' `fromto' } else { if `nomord'==2 { _estadd_prchange_GetEqnmNomModl `theoutcome' } _estadd_prchange_PostMat r(change`theoutcome'), prefix(`prefix') /// name(dc) `pattern' `binary' `continuous' `fromto' eq(`eq') } } if `"`base'"'=="" { _estadd_prchange_PostMat r(baseval), prefix(`prefix') name(X) } if `"`pattern'"'=="" { _estadd_prchange_dcNote, prefix(`prefix') name(dc) `binary' `continuous' } end program define _estadd_prchange_dcNote syntax [ , prefix(str) name(str) binary(str) continuous(str) ] local res `""{res:minmax} change" "{res:01} change" "{res:delta} change" "{res:sd} change" "{res:margefct}""' local bres: word `binary' of `res' local cres: word `continuous' of `res' di _n as txt `"first row in e(dc) contains:"' di _n `" `bres' for binary variables"' di `" `cres' for continuous variables"' end program define _estadd_prchange_PostMat, eclass syntax anything, name(str) [ Fromto eq(str) prefix(str) /// pattern(passthru) binary(passthru) continuous(passthru) ] capt confirm matrix `anything' if _rc exit tempname tmp1 local nmlist "`name'" matrix `tmp1' = `anything' if `"`eq'"'!="" { mat coleq `tmp1' = `"`eq'"' } if `"`pattern'`binary'`continuous'"'!="" { tempname pattmat _estadd_prchange_Merge `tmp1', pattmat(`pattmat') `pattern' `binary' `continuous' `fromto' } if "`fromto'"!="" { local nmlist "`nmlist' `name'from `name'to" tempname tmp tmp2 tmp3 mat rename `tmp1' `tmp' local r = rowsof(`tmp') local i = 1 while (`i'<=`r') { if (`r'-`i')>=2 { mat `tmp2' = nullmat(`tmp2') \ `tmp'[`i++',1...] // from mat `tmp3' = nullmat(`tmp3') \ `tmp'[`i++',1...] // to } mat `tmp1' = nullmat(`tmp1') \ `tmp'[`i++',1...] } mat drop `tmp' } local i 0 foreach nm of local nmlist { local ++i local rown: rown `tmp`i'' mat rown `tmp`i'' = `rown' // fix problem with leading blanks in equations ereturn matrix `prefix'`nm' = `tmp`i'' added_matrix `prefix'`nm' _rown } if `"`pattmat'"'!="" { ereturn matrix `prefix'pattern = `pattmat' added_matrix `prefix'pattern } end program define _estadd_prchange_Merge syntax name(name=tmp1) [, pattmat(str) pattern(str) binary(str) continuous(str) fromto ] tempname tmp mat rename `tmp1' `tmp' local r = cond("`fromto'"!="", 3, 1) mat `tmp1' = `tmp'[1..`r',1...]*. mat `pattmat' = `tmp'[1,1...]*. local rtot = rowsof(`tmp') mat rown `tmp1' = main mat rown `pattmat' = :type local vars: colnames `tmp1' local eqs: coleq `tmp1', quoted local j 0 foreach var of local vars { local ++j gettoken eq eqs : eqs if `"`eq'"'!=`"`lasteq'"' gettoken type rest : pattern else gettoken type rest : rest local lasteq `"`eq'"' if `"`type'"'=="" { capt assert `var'==0|`var'==1 if e(sample) & `var'<. if _rc local type `continuous' else local type `binary' } local ii = (`type'-1)*`r'+1 forv i = 1/`r' { if `r'>1 & `i'<3 & `ii'>=`rtot' { mat `tmp1'[`i',`j'] = .z } else { mat `tmp1'[`i',`j'] = `tmp'[`ii++',`j'] } } mat `pattmat'[1,`j'] = `type' } mat `tmp1' = `tmp1' \ `tmp' end program define _estadd_prchange_GatherNomChMat args mat noavg local cmd `"`e(cmd)'"' tempname tmpmat if `"`noavg'"'=="" { mat `tmpmat' = r(changemn) mat coleq `tmpmat' = `"Avg|Chg|"' mat `mat' = `tmpmat' } if `"`cmd'"'=="mlogit" { if c(stata_version) < 9 local outcat cat else local outcat out local k_cat = e(k_`outcat') local eqnames `"`e(eqnames)'"' if `k_cat'>`:list sizeof eqnames' { // no base equation local ibase = e(ibase`outcat') local baselab `"`e(baselab)'"' if `"`baselab'"'=="" { local baselab `"`e(base`outcat')'"' } forv i = 1/`k_cat' { if `i'==`ibase' { local eq `"`"`baselab'"'"' } else gettoken eq eqnames : eqnames, quotes local temp `"`temp' `eq'"' } local eqnames: list retok temp } local i 0 foreach eq of local eqnames { local ++i local theoutcome: di el(e(`outcat'),1,`i') mat `tmpmat' = r(change`theoutcome') mat coleq `tmpmat' = `"`eq'"' mat `mat' = nullmat(`mat'), `tmpmat' } } else if `"`cmd'"'=="mprobit" { local eqnames `"`e(outeqs)'"' local i 0 foreach eq of local eqnames { local ++i local theoutcome: di el(e(outcomes),`i',1) mat `tmpmat' = r(change`theoutcome') mat coleq `tmpmat' = `"`eq'"' mat `mat' = nullmat(`mat'), `tmpmat' } } else { // ordered models local eqnames : colnames r(catval) local i 0 foreach eq of local eqnames { local ++i local theoutcome: di el(r(catval),1,`i') mat `tmpmat' = r(change`theoutcome') mat coleq `tmpmat' = `"`eq'"' mat `mat' = nullmat(`mat'), `tmpmat' } } end program define _estadd_prchange_GetEqnmNomModl args theoutcome local cmd `"`e(cmd)'"' if `"`cmd'"'=="mlogit" { if c(stata_version) < 9 local outcat cat else local outcat out local k_cat = e(k_`outcat') local eqnames `"`e(eqnames)'"' local nobase = (`k_cat'>`:list sizeof eqnames') if `nobase' { local ibase = e(ibase`outcat') local baselab `"`e(baselab)'"' } forv i = 1/`k_cat' { if `nobase' { if `i'==`ibase' { local eq `"`baselab'"' } else gettoken eq eqnames : eqnames } else gettoken eq eqnames : eqnames if el(e(`outcat'),1,`i')==`theoutcome' { local value `"`eq'"' continue, break } } } else if `"`cmd'"'=="mprobit" { local eqnames `"`e(outeqs)'"' local i 0 foreach eq of local eqnames { if el(e(outcomes),`++i',1)==`theoutcome' { local value `"`eq'"' continue, break } } } if `"`value'"'=="" local value `theoutcome' c_local eq `"`value'"' end program define _estadd_prchange_StoreEachOutc // only for nomord models syntax anything [, nomord(str) nobase fromto prefix(passthru) /// pattern(passthru) binary(passthru) continuous(passthru) ] // backup estimates tempname hcurrent _est hold `hcurrent', copy restore estsystem if `"`nomord'"'=="2" { // backup b and V tempname b bi V Vi mat `b' = e(b) mat `V' = e(V) } // cycle through categories local k_kat = colsof(r(predval)) tempname catval catvali mat `catval' = r(catval) forv i=1/`k_kat' { mat `catvali' = `catval'[1...,`i'] local catlabi: colnames `catvali' local catnumi: di `catvali'[1,1] if `"`nomord'"'=="2" { _estadd_prchange_GetEqnmNomModl `catnumi' if colnumb(`b', `"`eq':"')<. { mat `bi' = `b'[1...,`"`eq':"'] mat `Vi' = `V'[`"`eq':"',`"`eq':"'] } else { // base outcome; get first eq and set zero local tmp : coleq `b', q gettoken tmp : tmp mat `bi' = `b'[1...,`"`tmp':"'] * 0 mat `Vi' = `V'[`"`tmp':"',`"`tmp':"'] * 0 } mat coleq `bi' = "" mat coleq `Vi' = "" mat roweq `Vi' = "" erepost b=`bi' V=`Vi' } `qui' _estadd_prchange_AddStuffToE, nomord(1) outcome(`i') /// `base' `fromto' `pattern' `binary' `continuous' `prefix' `qui' di "" local qui qui _eststo `anything'`catnumi', title(`"`catlabi'"') // store without e(sample) di as txt "results for outcome " as res `catnumi' /// as txt " stored as " as res "`anything'`catnumi'" } // retore estimates _est unhold `hcurrent' end * 22. * -estadd- subroutine: support for -prvalue- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_prvalue, eclass version 9.2 local caller : di _caller() syntax [anything] [if] [in] [ , Prefix(passthru) Replace Quietly /// LABel(str) Title(passthru) swap Diff * ] // post if `"`anything'"'!="" { gettoken post post2 : anything if `"`post'"'!="post" { di as err `"`post' not allowed"' exit 198 } else if `"`label'"'!="" { di as err "label() not allowed" exit 198 } _estadd_prvalue_Post `post2' `if' `in', `prefix' `replace' `quietly' /// `title' `swap' `diff' `options' exit } else if `"`title'"'!="" { di as err "title() not allowed" exit 198 } else if "`swap'"!="" { di as err "swap not allowed" exit 198 } // look for e(sample) confirm_esample // run prvalue capt findfile prvalue.ado if _rc { di as error "-prvalue- from the -spost9_ado- package by Long and Freese required" di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"' error 499 } `quietly' version `caller': prvalue `if' `in', `diff' `options' // append? capture confirm existence `e(_estadd_prvalue)' local append = (_rc==0) & ("`replace'"=="") tempname prvalue prvalue_x prvalue_x2 if `append' { mat `prvalue' = e(_estadd_prvalue) mat `prvalue_x' = e(_estadd_prvalue_x) capt mat `prvalue_x2' = e(_estadd_prvalue_x2) local ires = rowsof(`prvalue') + 1 } else local ires 1 if `"`label'"'=="" { local label "pred`ires'" } else { local label = substr(`"`label'"', 1, 30) // 30 characters max local problemchars `": . `"""'"' foreach char of local problemchars { local label: subinstr local label `"`char'"' "_", all } } // collect results tempname pred mat `pred' = r(pred) if `"`diff'"'!="" { _estadd_prvalue_GetRidOfD `pred' } _estadd_prvalue_ReshapePred `pred', label(`label') _estadd_prvalue_AddPred `prvalue' `pred' `append' _estadd_prvalue_AddX `prvalue_x', label(`label') capture confirm matrix r(x2) local hasx2 = _rc==0 if `hasx2' { _estadd_prvalue_AddX `prvalue_x2', label(`label') two } // post in e() di as txt _n cond(`append',"updated","added") " matrices:" ereturn matrix _estadd_prvalue = `prvalue' added_matrix _estadd_prvalue ereturn matrix _estadd_prvalue_x = `prvalue_x' added_matrix _estadd_prvalue_x if `hasx2' { ereturn matrix _estadd_prvalue_x2 = `prvalue_x2' added_matrix _estadd_prvalue_x2 } end program _estadd_prvalue_GetRidOfD args pred local coln: colnames `pred' local firstcol: word 1 of `coln' local nfirstcol = substr("`firstcol'",2,.) local coln : subinstr local coln "`firstcol'" "`nfirstcol'" , word mat coln `pred' = `coln' end program _estadd_prvalue_ReshapePred syntax anything, label(str) tempname tmp res local r = rowsof(`anything') forv i=1/`r' { mat `tmp' = `anything'[`i',1...] local nm: rownames `tmp' mat coleq `tmp' = `"`nm'"' mat `res' = nullmat(`res'), `tmp' } mat rown `res' = `"`label'"' mat `anything' = `res' end program _estadd_prvalue_AddPred args prvalue pred append if `append' { local coln1: colfullnames `prvalue' local coln2: colfullnames `pred' if `"`coln1'"'!=`"`coln2'"' { di as err "incompatible prvalue results" exit 498 } } mat `prvalue' = nullmat(`prvalue') \ `pred' end program _estadd_prvalue_AddX syntax anything, label(str) [ two ] if "`two'"!="" local two 2 tempname tmp mat `tmp' = r(x`two') mat rown `tmp' = `"`label'"' mat `anything' = nullmat(`anything') \ `tmp' end program _estadd_prvalue_Post, eclass syntax [name(name=post2)] [ , Prefix(name) Replace Quietly /// Title(passthru) swap ] capture confirm matrix e(_estadd_prvalue) if _rc { di as err "prvalue results not found" exit 498 } // backup estimates tempname hcurrent _est hold `hcurrent', copy restore estsystem local cmd = e(cmd) local depvar = e(depvar) local N = e(N) local estname `"`e(_estadd_estimates_name)'"' // get results tempname prvalue prvalue_x prvalue_x2 mat `prvalue' = e(_estadd_prvalue) mat `prvalue_x' = e(_estadd_prvalue_x) capture confirm matrix e(_estadd_prvalue_x2) local hasx2 = _rc==0 if `hasx2' { mat `prvalue_x2' = e(_estadd_prvalue_x2) } // return prvalues tempname tmp tmp2 b se if "`swap'"=="" { local eqs: coleq `prvalue', q local eqs: list uniq eqs foreach eq of local eqs { mat `tmp' = `prvalue'[1...,`"`eq':"'] mat `tmp2' = `tmp'[1...,1]' mat coleq `tmp2' = `"`eq'"' mat roweq `tmp2' = "" mat `b' = nullmat(`b'), `tmp2' mat `tmp2' = `tmp'[1...,`"`eq':SE"']' mat coleq `tmp2' = `"`eq'"' mat roweq `tmp2' = "" mat `se' = nullmat(`se'), `tmp2' } mat drop `tmp' `tmp2' } else { local r = rowsof(`prvalue') local c = colsof(`prvalue') local coln: colnames `prvalue' local eqs: coleq `prvalue', q mat coln `prvalue' = `eqs' mat coleq `prvalue' = `coln' local coln: list uniq coln local ncol: list sizeof coln local icol: list posof "SE" in coln forv i=1/`r' { mat `tmp' = `prvalue'[`i',1...] local labl : rownames `tmp' forv j=1(`ncol')`c' { mat `tmp2' = nullmat(`tmp2'), `tmp'[1...,`j'] } mat coleq `tmp2' = `"`labl'"' mat `b' = nullmat(`b'), `tmp2' mat drop `tmp2' forv j=`icol'(`ncol')`c' { mat `tmp2' = nullmat(`tmp2'), `tmp'[1...,`j'] } mat coleq `tmp2' = `"`labl'"' mat `se' = nullmat(`se'), `tmp2' mat drop `tmp2' } mat drop `tmp' } ereturn post `b', obs(`N') ereturn local model "`cmd'" ereturn local cmd "estadd_prvalue" ereturn local depvar "`depvar'" di as txt _n "scalars:" added_scalar N di as txt _n "macros:" added_macro depvar added_macro cmd added_macro model added_macro properties di as txt _n "matrices:" added_matrix b "predictions" ereturn matrix se = `se' added_matrix se "standard errors" local istat 0 foreach stat in LB UB Category Cond { local elabel: word `++istat' of "lower CI bounds" "upper CI bounds" /// "outcome values" "conditional predictions" if "`swap'"=="" { foreach eq of local eqs { local colnumb = colnumb(`prvalue',`"`eq':`stat'"') if `colnumb'>=. continue mat `tmp2' = `prvalue'[1...,`colnumb']' mat coleq `tmp2' = `"`eq'"' mat roweq `tmp2' = "" mat `tmp' = nullmat(`tmp'), `tmp2' } } else { local icol: list posof "`stat'" in coln if `icol'==0 continue forv i=1/`r' { mat `tmp2' = `prvalue'[`i',1...] local labl : rownames `tmp2' mat coleq `tmp2' = `"`labl'"' forv j=`icol'(`ncol')`c' { mat `tmp' = nullmat(`tmp'), `tmp2'[1...,`j'] } } mat drop `tmp2' } capt confirm matrix `tmp' if _rc==0 { ereturn matrix `prefix'`stat' = `tmp' added_matrix `prefix'`stat' "`elabel'" } } // return x-values matrix `prvalue_x' = `prvalue_x'' ereturn matrix `prefix'X = `prvalue_x' added_matrix `prefix'X _rown if `hasx2' { matrix `prvalue_x2' = `prvalue_x2'' ereturn matrix `prefix'X2 = `prvalue_x2' added_matrix `prefix'X2 _rown } // store if "`post2'"!="" { _eststo `estname'`post2', `title' di as txt _n "results stored as " as res "`estname'`post2'" } else if `"`title'"'!="" { estimates change ., `title' } // retore estimates if "`post2'"!="" { _est unhold `hcurrent' } else { _est unhold `hcurrent', not } end * 23. * -estadd- subroutine: support for -asprvalue- by Long and Freese * (see http://www.indiana.edu/~jslsoc/spost.htm) program define estadd_asprvalue, eclass version 9.2 local caller : di _caller() syntax [anything] [ , Prefix(passthru) Replace Quietly /// LABel(str) Title(passthru) swap * ] // post if `"`anything'"'!="" { gettoken post post2 : anything if `"`post'"'!="post" { di as err `"`post' not allowed"' exit 198 } else if `"`label'"'!="" { di as err "label() not allowed" exit 198 } _estadd_asprvalue_Post `post2' , `prefix' `replace' `quietly' /// `title' `swap' `options' exit } else if `"`title'"'!="" { di as err "title() not allowed" exit 198 } else if "`swap'"!="" { di as err "swap not allowed" exit 198 } // look for e(sample) confirm_esample // run prvalue capt findfile asprvalue.ado if _rc { di as error "-asprvalue- from the -spost9_ado- package by Long and Freese required" di as error `"type {stata "net from http://www.indiana.edu/~jslsoc/stata"}"' error 499 } `quietly' version `caller': asprvalue , `options' // append? capture confirm existence `e(_estadd_asprval)' local append = (_rc==0) & ("`replace'"=="") tempname asprval asprval_asv asprval_csv if `append' { mat `asprval' = e(_estadd_asprval) capt mat `asprval_asv' = e(_estadd_asprval_asv) capt mat `asprval_csv' = e(_estadd_asprval_csv) local ires = rowsof(`asprval') + 1 } else local ires 1 if `"`label'"'=="" { local label "pred`ires'" } else { local label = substr(`"`label'"', 1, 30) // 30 characters max local problemchars `": . `"""'"' foreach char of local problemchars { local label: subinstr local label `"`char'"' "_", all } } // collect results tempname res mat `res' = r(p) _estadd_asprvalue_Reshape `res', label(`label') _estadd_asprvalue_Add `asprval' `res' `append' capture confirm matrix r(asv) local hasasv = _rc==0 if `hasasv' { mat `res' = r(asv) _estadd_asprvalue_Reshape `res', label(`label') _estadd_asprvalue_Add `asprval_asv' `res' `append' } capture confirm matrix r(csv) local hascsv = _rc==0 if `hascsv' { _estadd_asprvalue_AddCsv `asprval_csv', label(`label') } // post in e() di as txt _n cond(`append',"updated","added") " matrices:" ereturn matrix _estadd_asprval = `asprval' added_matrix _estadd_asprval if `hasasv' { ereturn matrix _estadd_asprval_asv = `asprval_asv' added_matrix _estadd_asprval_asv } if `hascsv' { ereturn matrix _estadd_asprval_csv = `asprval_csv' added_matrix _estadd_asprval_csv } end program _estadd_asprvalue_Reshape syntax anything, label(str) tempname tmp res local r = rowsof(`anything') forv i=1/`r' { mat `tmp' = `anything'[`i',1...] local nm: rownames `tmp' mat coleq `tmp' = `"`nm'"' mat `res' = nullmat(`res'), `tmp' } mat rown `res' = `"`label'"' mat `anything' = `res' end program _estadd_asprvalue_Add args master using append if `append' { local coln1: colfullnames `master' local coln2: colfullnames `using' if `"`coln1'"'!=`"`coln2'"' { di as err "incompatible asprvalue results" exit 498 } } mat `master' = nullmat(`master') \ `using' end program _estadd_asprvalue_AddCsv syntax anything, label(str) tempname tmp mat `tmp' = r(csv) mat rown `tmp' = `"`label'"' mat `anything' = nullmat(`anything') \ `tmp' end program _estadd_asprvalue_Post, eclass syntax [name(name=post2)] [ , Prefix(name) Replace Quietly /// Title(passthru) swap ] capture confirm matrix e(_estadd_asprval) if _rc { di as err "asprvalue results not found" exit 498 } // backup estimates tempname hcurrent _est hold `hcurrent', copy restore estsystem local cmd = e(cmd) local depvar = e(depvar) local N = e(N) local estname `"`e(_estadd_estimates_name)'"' // get results tempname asprval asprval_asv asprval_csv mat `asprval' = e(_estadd_asprval) capture confirm matrix e(_estadd_asprval_asv) local hasasv = _rc==0 if `hasasv' { mat `asprval_asv' = e(_estadd_asprval_asv) } capture confirm matrix e(_estadd_asprval_csv) local hascsv = _rc==0 if `hascsv' { mat `asprval_csv' = e(_estadd_asprval_csv) } // return predictions tempname tmp tmp2 b if "`swap'"=="" { local eqs: coleq `asprval', q local eqs: list uniq eqs foreach eq of local eqs { mat `tmp' = `asprval'[1...,`"`eq':"'] mat `tmp2' = `tmp'[1...,1]' mat coleq `tmp2' = `"`eq'"' mat roweq `tmp2' = "" mat `b' = nullmat(`b'), `tmp2' } mat drop `tmp' `tmp2' } else { local r = rowsof(`asprval') local coln: colnames `asprval' local eqs: coleq `asprval', q mat coln `asprval' = `eqs' forv i=1/`r' { mat `tmp' = `asprval'[`i',1...] local labl : rownames `tmp' mat coleq `tmp' = `"`labl'"' mat `b' = nullmat(`b'), `tmp' } mat drop `tmp' } ereturn post `b', obs(`N') ereturn local model "`cmd'" ereturn local cmd "estadd_asprvalue" ereturn local depvar "`depvar'" di as txt _n "scalars:" added_scalar N di as txt _n "macros:" added_macro depvar added_macro cmd added_macro model added_macro properties di as txt _n "matrices:" added_matrix b "predictions" // return asv-values if `hasasv' { if "`swap'"=="" { local vars: coleq `asprval_asv' local vars: list uniq vars local cats: colnames `asprval_asv' local cats: list uniq cats foreach var of local vars { foreach cat of local cats { mat `tmp2' = `asprval_asv'[1...,`"`var':`cat'"']' mat coleq `tmp2' = `"`cat'"' mat roweq `tmp2' = "" mat `tmp' = nullmat(`tmp'), `tmp2' } mat rown `tmp' = `"`var'"' mat `b' = nullmat(`b') \ `tmp' mat drop `tmp' } } else { local r = rowsof(`asprval_asv') local vars: coleq `asprval_asv' local vars: list uniq vars forv i=1/`r' { foreach var of local vars { mat `tmp2' = `asprval_asv'[`i',`"`var':"'] local lbl: rownames `tmp2' mat coleq `tmp2' = `"`lbl'"' mat rown `tmp2' = `"`var'"' mat `tmp' = nullmat(`tmp') \ `tmp2' } mat `b' = nullmat(`b') , `tmp' mat drop `tmp' } } ereturn matrix `prefix'asv = `b' added_matrix `prefix'asv _rown } // return csv-values if `hascsv' { matrix `asprval_csv' = `asprval_csv'' ereturn matrix `prefix'csv = `asprval_csv' added_matrix `prefix'csv _rown } // store if "`post2'"!="" { _eststo `estname'`post2', `title' di as txt _n "results stored as " as res "`estname'`post2'" } else if `"`title'"'!="" { estimates change ., `title' } // retore estimates if "`post2'"!="" { _est unhold `hcurrent' } else { _est unhold `hcurrent', not } end * 24. estadd_margins program define estadd_margins, eclass version 11.0 local caller : di _caller() syntax [ anything(everything equalok)] [fw aw iw pw] [, Prefix(name) Replace Quietly * ] // set default prefix if "`prefix'"=="" local prefix "margins_" // compute and return the results if `"`weight'`exp'"'!="" local wgtexp `"[`weight'`exp']"' `quietly' version `caller': margins `anything' `wgtexp', `options' // check names local rscalars: r(scalars) local rmacros: r(macros) local rmatrices: r(matrices) local rmatrices: subinstr local rmatrices "V" "se", word if "`replace'"=="" { foreach nmlist in rscalars rmacros rmatrices { foreach name of local `nmlist' { confirm_new_ename `prefix'`name' } } } // add results di as txt _n "added scalars:" foreach name of local rscalars { ereturn scalar `prefix'`name' = r(`name') added_scalar `prefix'`name' } di as txt _n "added macros:" foreach name of local rmacros { ereturn local `prefix'`name' `"`r(`name')'"' added_macro `prefix'`name' } di as txt _n "added matrices:" tempname tmpmat foreach name of local rmatrices { if "`name'"=="se" { mat `tmpmat' = vecdiag(r(V)) forv i = 1/`=colsof(`tmpmat')' { mat `tmpmat'[1,`i'] = sqrt(`tmpmat'[1,`i']) } } else { mat `tmpmat' = r(`name') } eret matrix `prefix'`name' = `tmpmat' added_matrix `prefix'`name' } end * 99. * copy of erepost.ado, version 1.0.1, Ben Jann, 30jul2007 * used by estadd_listcoef and estadd_prchange prog erepost, eclass version 8.2 syntax [anything(equalok)] [, cmd(str) noEsample Esample2(varname) REName /// Obs(passthru) Dof(passthru) PROPerties(passthru) * ] if "`esample'"!="" & "`esample2'"!="" { di as err "only one allowed of noesample and esample()" exit 198 } // parse [b = b] [V = V] if `"`anything'"'!="" { tokenize `"`anything'"', parse(" =") if `"`7'"'!="" error 198 if `"`1'"'=="b" { if `"`2'"'=="=" & `"`3'"'!="" { local b `"`3'"' confirm matrix `b' } else error 198 if `"`4'"'=="V" { if `"`5'"'=="=" & `"`6'"'!="" { local v `"`6'"' confirm matrix `b' } else error 198 } else if `"`4'"'!="" error 198 } else if `"`1'"'=="V" { if `"`4'"'!="" error 198 if `"`2'"'=="=" & `"`3'"'!="" { local v `"`3'"' confirm matrix `v' } else error 198 } else error 198 } //backup existing e()'s if "`esample2'"!="" { local sample "`esample2'" } else if "`esample'"=="" { tempvar sample gen byte `sample' = e(sample) } local emacros: e(macros) if `"`properties'"'!="" { local emacros: subinstr local emacros "properties" "", word } foreach emacro of local emacros { local e_`emacro' `"`e(`emacro')'"' } local escalars: e(scalars) if `"`obs'"'!="" { local escalars: subinstr local escalars "N" "", word } if `"`dof'"'!="" { local escalars: subinstr local escalars "df_r" "", word } foreach escalar of local escalars { tempname e_`escalar' scalar `e_`escalar'' = e(`escalar') } local ematrices: e(matrices) if "`b'"=="" & `:list posof "b" in ematrices' { tempname b mat `b' = e(b) } if "`v'"=="" & `:list posof "V" in ematrices' { tempname v mat `v' = e(V) } local bV "b V" local ematrices: list ematrices - bV foreach ematrix of local ematrices { tempname e_`ematrix' matrix `e_`ematrix'' = e(`ematrix') } // rename if "`b'"!="" & "`v'"!="" & "`rename'"!="" { local eqnames: coleq `b', q local vnames: colnames `b' mat coleq `v' = `eqnames' mat coln `v' = `vnames' mat roweq `v' = `eqnames' mat rown `v' = `vnames' } // post results if "`esample'"=="" { eret post `b' `v', esample(`sample') `obs' `dof' `properties' `options' } else { eret post `b' `v', `obs' `dof' `properties' `options' } foreach emacro of local emacros { eret local `emacro' `"`e_`emacro''"' } if `"`cmd'"'!="" { eret local cmd `"`cmd'"' } foreach escalar of local escalars { eret scalar `escalar' = scalar(`e_`escalar'') } foreach ematrix of local ematrices { eret matrix `ematrix' = `e_`ematrix'' } end