*! igesetci v 1.0 *! Pablo Mitnik *! *! Post-estimation command that computes Imbens and Manski's (2004) and Nevo and Rosen's (2012) *! confidence intervals for partially identified parameters when the parameter is an intergenerational elasticity *! *! Last updated Feb. 2019 program igesetci, rclass version 13 syntax varlist(min=2 max=2), lb(string) ub(string) ige(string) [ci(string) level(cilevel)] local cvar : word 1 of `varlist' local pvar : word 2 of `varlist' if "`ci'" == "" local ci im /*1. Check inputs*/ if "`ige'" != "igeg" & "`ige'" != "igee" { di as error "ige option may only be igeg or igee" exit 198 } if "`ci'" != "im" & "`ci'" != "nr" & "`ci'" != "imnr" { di as error "ci option may only be im or nr or imnr" exit 198 } tempname cmodel _estimates hold `cmodel', nullok copy qui { foreach model in `lb' `ub' { capture estimates restore `model' if _rc!=0 { noi di as error "estimation results from model `model' are not stored" exit 198 } local matvars : colfullnames e(b) local ispvarthere = 0 if "`ige'"=="igeg" { foreach var in `matvars' { if "`var'"=="`pvar'" local ispvarthere = 1 } if `ispvarthere'==0 { noi di as error "IGE estimate for parental variable `pvar' is not included in the results of model `model'" _estimates unhold `cmodel' exit 198 } } else if "`ige'"=="igee" { foreach var in `matvars' { if "`var'"=="`cvar':`pvar'" local ispvarthere = 1 } if `ispvarthere'==0 { noi di as error "IGE estimate for parental variable `cvar':`pvar' is not included in the results of model `model'" _estimates unhold `cmodel' exit 198 } } } local nmodelsub: word count `ub' local nmodelslb: word count `lb' if `nmodelsub' > 1 | `nmodelslb' > 1 { noi di as error "{cmd:igesetci} computes confidence intervals for an individual set estimate" noi di as error "use {cmd:igeintbounds} for estimation and inference with an intersection-bounds estimator of an IGE" exit 198 } estimates restore `lb' if "`ige'"=="igeg" & "`e(cmd)'"!="regress" { noi di as error "with ige igeg, lower bound estimate needs to be computed with command {cmd:regress} but model `lb' is based on a different command" _estimates unhold `cmodel' exit 198 } if "`ige'"=="igee" & "`e(cmd)'"!="poisson" { noi di as error "with ige igee, lower bound estimate needs to be computed with command {cmd:poisson} but model `lb' is based on a different command" _estimates unhold `cmodel' exit 198 } local N_lb = e(N) estimates restore `ub' if "`ige'"=="igeg" & "`e(cmd)'"!="ivregress" { noi di as error "with ige igeg, upper bound estimate needs to be computed with command {cmd:ivregress} but model `ub' is based on a different command" _estimates unhold `cmodel' exit 198 } if "`ige'"=="igee" & "`e(cmd)'"!="ivpoisson" { noi di as error "with ige igee, upper bound estimate needs to be computed with command {cmd:ivpoisson} but model `ub' is based on a different command" _estimates unhold `cmodel' exit 198 } local N_ub = e(N) if `N_lb' != `N_ub' { noi di as error "samples sizes for the lower-bound and upper-bound models are different" exit 198 } else if `N_lb' == `N_ub' local n = `N_lb' } /*ends qui*/ /*2. Compute and report requested confidence interval*/ if "`ige'"=="igeg" local fullvar `pvar' else if "`ige'"=="igee" local fullvar `cvar':`pvar' /*linear IV or GMM IVP estimate*/ qui estimates restore `ub' tempname sub_pe sub_se scalar `sub_pe' = _b[`fullvar'] scalar `sub_se' = _se[`fullvar'] /*OLS or PPML estimate*/ qui estimates restore `lb' tempname slb_pe slb_se scalar `slb_pe' = _b[`fullvar'] scalar `slb_se' = _se[`fullvar'] if "`ci'"=="im" | "`ci'"=="imnr" { /*Relative width*/ global RW = (`sub_pe' - `slb_pe') / max(`slb_se', `sub_se') /*Compute c */ tempvar Y gen `Y' = 0 qui replace `Y' = `level'/100 in 1 qui nl igesetci @ `Y', parameters(c) initial(c 1.64) tempname c ci_im_lb ci_im_ub scalar `c' = _b[_cons] scalar `ci_im_lb' = `slb_pe' - `c' * `slb_se' scalar `ci_im_ub' = `sub_pe' + `c' * `sub_se' } if "`ci'"=="nr" | "`ci'"=="imnr" { tempname deltan pn k ci_nr_lb ci_nr_ub scalar `deltan' = `sub_pe' - `slb_pe' scalar `pn' = 1 - normal(ln(`n') * `deltan') * (1 - (`level'/100)) scalar `k' = invnormal(`pn') scalar `ci_nr_lb' = `slb_pe' - `k' * `slb_se' scalar `ci_nr_ub' = `sub_pe' + `k' * `sub_se' } /*Return and display results*/ if "`ige'"=="igeg" local rige IGE of geometric mean else if "`ige'"=="igee" local rige IGE of expectation return scalar confidence_level = `level' if "`ci'"=="im" | "`ci'"=="imnr" { return scalar c = `c' return scalar ci_im_ub = `ci_im_ub' return scalar ci_im_lb = `ci_im_lb' } if "`ci'"=="nr" | "`ci'"=="imnr" { return scalar k = `k' return scalar ci_nr_ub = `ci_nr_ub' return scalar ci_nr_lb = `ci_nr_lb' } return scalar pe_ub = `sub_pe' return scalar pe_lb = `slb_pe' return local model_ub "`ub'" return local model_lb "`lb'" return local ci "`ci'" return local ige "`ige'" return local cmd "igesetci" di as txt "{hline 70}" di as text "Partially identified `rige', based on estimates" di as text "from stored models `lb' (lower bound) and `ub' (upper bound)" di as text "" di as text _col(6) "Set estimate" _col(31) as res %6.5f `slb_pe' _col(39) as res "- " %6.5f `sub_pe' if "`ci'"=="im" | "`ci'"=="imnr" di as text _col(6) "`level'% IM Conf. interval" _col(31) as res %6.5f `ci_im_lb' _col(39) as res "- " %6.5f `ci_im_ub' if "`ci'"=="nr" | "`ci'"=="imnr" di as text _col(6) "`level'% NR Conf. interval" _col(31) as res %6.5f `ci_nr_lb' _col(39) as res "- " %6.5f `ci_nr_ub' di as txt "{hline 70}" if "`ci'"=="im" { di as txt "Note: The confidence interval is Imbens and Manski's (2004)" di as txt " confidence interval for a partially-identified parameter" } if "`ci'"=="nr" { di as txt "Note: The confidence interval is Nevo and Rosen's (2012: Sec. IV)" di as txt " confidence interval for a partially-identified parameter" } if "`ci'"=="imnr" { di as txt "Note: The IM and NR confidence intervals are Imbens and Manski's" di as txt " (2004) and Nevo and Rosen's (2012: Sec. IV) confidence" di as txt " intervals for a partially-identified parameter, respectively" } di as txt "" end