// ------------------------------------------------------ // Authors: Mathias Sinning (mathias.sinning@anu.edu.au) // Markus Hahn (mhahn@unimelb.edu.au) // // Date : August 19, 2008 // ------------------------------------------------------- program define nldecompose version 10 * parse syntax capture _on_colon_parse `0' if !_rc { local regcmd `"`s(after)'"' local 0 `"`s(before)'"' } else { syntax, regcmd(string asis) [*] local 0 , `options' } syntax, [bootstrap] [bs] [BSOptions(string asis)] [bs_step] [THREEfold] [omega(passthru)] [*] if "`bs'" != "" { if "`bootstrap'" == "" { local bootstrap = "bootstrap" } else { di as error "You are not allowed to specify and at the same time!" error 99999 } } if "`bootstrap'" == "" { if "`bs_step'" == "" { nld_dropnlds } nld_decomposition `", `threefold' `omega' `options'"' `"`regcmd'"' if "`bs_step'" == "" { nld_setreturns ereturn clear sreturn clear } } else { nld_dropnlds // exps for bootstrap if "`threefold'" == "" { local exps raw charAB coefAB charBA coefBA } else { local exps raw charAB coefAB intAB charBA coefBA intBA } if "`omega'" != "" { local exps `exps' prod adv disadv } foreach exp of local exps { local nld_exps `nld_exps' nld_`exp' } qui bootstrap `nld_exps', `bsoptions': nldecompose, regcmd(`regcmd') bs_step `threefold' `omega' `options' nld_create_bootstrap_nlds `exps' nld_setreturns ereturn clear sreturn clear } if "`bs_step'" == "" { nld_output, `bootstrap' } end program define nld_decomposition, rclass args 0 regcmd syntax , BY(varname) [THREEfold] [omega(string)] [REGOUTput] [ll(string)] [ul(string)] global nld_threefold `threefold' global nld_omega `omega' nld_parse_regcmd `regcmd' local svy `r(svy)' // only not empty if "svy:" prefix was specified local regmodel `r(regcmd)' local 0 `r(rest)' syntax varlist(min=2) [if/] [in] [aweight iweight pweight fweight], * if `"`if'"' == "" { local if = 1 } if "`weight'" != "" { local wght = `"[`weight' `exp']"' } if "`regoutput'" != "regoutput" { local regquietly quietly } nld_getcmd `regmodel' local regcmd `r(cmd)' ///////////////////////////////// tempvar group qui gen double `group' = 1-`by' * temporary variables / scalars tempvar sampleA sampleB foreach X in A B AB BA { tempname _expval`X' scalar `_expval`X'' = 0 tempname c_expval`X' scalar `c_expval`X'' = 0 } tempname result // result matrix tempname sigmaA sigmaB tempname raw // matrices tempname getbA betaA gammaA nameA est_b cats getbB betaB gammaB getb beta_star gamma_star beta_1 gamma_1 gamma_mat gamma_vec diag1 diag2 diag1_g diag2_g inv inv_g omega_mat omega_vec out _O W W_gamma I I_gamma // ////////////////////////////////// * parse varlist nld_parse_varlist "`varlist'" "`regcmd'" local depvar `r(depvar)' local indvar `r(indvar)' * regressions * do regression for group A `regquietly' `svy' `regcmd' `depvar' `indvar' if (`group'==0) & (`if') `in' `wght', `options' qui gen byte `sampleA' = e(sample) est store A * get beta vector mat `getbA' = e(b) local dim1 = wordcount("`indvar'") local dim2 = colsof(`getbA') if ("`regcmd'"!="zip" & "`regcmd'"!="zinb" & "`regcmd'"!="ologit" & "`regcmd'"!="oprobit") { mat `betaA' = `getbA'[1,1..`dim1'+1] local k1 = `dim1'+1 } else if ("`regcmd'"=="ologit" | "`regcmd'"=="oprobit") { mat `betaA' = `getbA'[1,1..`dim1'] local k1 = `dim1' } else if ("`regcmd'"=="zip") { local k1 = `dim1'+1 mat `betaA' = `getbA'[1,1..`k1'] mat `gammaA' = `getbA'[1,`k1'+1..`dim2'] local k2 = colsof(`gammaA') mat `nameA' = `getbA'[1,`k1'+1..`dim2'-1] mat `nameA' = `nameA'' local namesA : rownames `nameA' } else if ("`regcmd'"=="zinb") { local k1 = `dim1'+1 mat `betaA' = `getbA'[1,1..`k1'] mat `gammaA' = `getbA'[1,`k1'+1..`dim2'-1] local k2 = colsof(`gammaA') mat `nameA' = `getbA'[1,`k1'+1..`dim2'-2] mat `nameA' = `nameA'' local namesA : rownames `nameA' } if "`k2'" == "" { local k2 = 0 } local obsA = e(N) // save number of observations * retrieve sigma - needed for censored and truncated regression models if ("`regcmd'"=="intreg" | "`regcmd'"=="truncreg") { scalar `sigmaA' = e(sigma) } else if ("`regcmd'"=="tobit") { scalar `sigmaA' = r(est) } * retrieve categories and threshold values - needed for ordered choice models if ("`regcmd'"=="ologit" | "`regcmd'"=="oprobit") { mat `est_b' = e(b) local k = colsof(`est_b') mat `cats' = e(cat) local category = colsof(`cats') local threshnum = `category'-1 forvalues num = 1/`threshnum' { local mathias = `k'-`threshnum'+ `num' scalar mu`num'A = `est_b'[1,`mathias'] } } * do regression for group B `regquietly' `svy' `regcmd' `depvar' `indvar' if (`group'==1) & (`if') `in' `wght', `options' qui gen byte `sampleB' = e(sample) est store B * get beta vector mat `getbB' = e(b) local dim1 = wordcount("`indvar'") local dim2 = colsof(`getbB') if ("`regcmd'"!="zip" & "`regcmd'"!="zinb" & "`regcmd'"!="ologit" & "`regcmd'"!="oprobit") { mat `betaB' = `getbB'[1,1..`dim1'+1] } else if ("`regcmd'"=="ologit" | "`regcmd'"=="oprobit") { mat `betaB' = `getbB'[1,1..`dim1'] } else if ("`regcmd'"=="zip") { mat `betaB' = `getbB'[1,1..`dim1'+1] mat `gammaB' = `getbB'[1,`dim1'+2..`dim2'] } else if ("`regcmd'"=="zinb") { mat `betaB' = `getbB'[1,1..`dim1'+1] mat `gammaB' = `getbB'[1,`dim1'+2..`dim2'-1] } local obsB = e(N) // save number of observations * retrieve sigma - needed for censored and truncated regression models if ("`regcmd'"=="intreg" | "`regcmd'"=="truncreg") { scalar `sigmaB' = e(sigma) } else if ("`regcmd'"=="tobit") { scalar `sigmaB' = r(est) } * retrieve categories and threshold values - needed for ordered choice models if ("`regcmd'"=="ologit" | "`regcmd'"=="oprobit") { mat `est_b' = e(b) local k = colsof(`est_b') mat `cats' = e(cat) local category_B = colsof(`cats') if `category_B'!=`category' { di as error "ERROR: dependent variables of group A and B have different number of categories" error 99999 } local threshnum = `category'-1 forvalues num = 1/`threshnum' { local mathias = `k'-`threshnum'+ `num' scalar mu`num'B = `est_b'[1,`mathias'] } } * temporary variables foreach X in A B AB BA { tempvar _pred`X' tempvar _pred2`X' tempvar _value`X' tempvar c_pred`X' tempvar c_pred2`X' tempvar c_value`X' } * predictions qui est restore A qui predict double `_predA' if `sampleA' == 1, xb qui predict double `_predAB' if `sampleB' == 1, xb // counterfactual if ("`regcmd'"=="zip" | "`regcmd'" == "zinb") { qui predict double `_pred2A' if `sampleA' == 1, xb equation(inflate) qui predict double `_pred2AB' if `sampleB' == 1, xb equation(inflate) } qui est restore B qui predict double `_predB' if `sampleB' == 1, xb qui predict double `_predBA' if `sampleA' == 1, xb // counterfactual if ("`regcmd'"=="zip" | "`regcmd'"=="zinb") { qui predict double `_pred2B' if `sampleB' == 1, xb equation(inflate) qui predict double `_pred2BA' if `sampleA' == 1, xb equation(inflate) } est drop A B * create omega matrix if "`omega'" != "" { * omega matrix proposed by Cotton (1988) if "`omega'" == "cotton" { if `obsA' >= `obsB' { local shareAB = `obsA'/(`obsA'+`obsB') local omega = `shareAB' } else if `obsA' < `obsB' { local shareAB = `obsB'/(`obsA'+`obsB') local omega = `shareAB' } } * omega matrix proposed by Reimers (1983) else if "`omega'" == "reimers" { local omega = .5 } * omega matrix proposed by Neumark (1988) else if ("`omega'" == "neumark") { `regquietly' `svy' `regcmd' `depvar' `indvar' if (`if') `in' `wght', `options' mat `getb' = e(b) if ("`regcmd'"!="zip" & "`regcmd'"!="zinb" & "`regcmd'"!="ologit" & "`regcmd'"!="oprobit") { mat `beta_star' = `getb'[1,1..`k1'] } else if ("`regcmd'"=="ologit" | "`regcmd'"=="oprobit") { mat `beta_star' = `getb'[1,1..`k1'] } else if ("`regcmd'"=="zip") { mat `beta_star' = `getb'[1,1..`k1'] mat `gamma_star' = `getb'[1,`k1'+1..`dim2'] } else if ("`regcmd'"=="zinb") { mat `beta_star' = `getb'[1,1..`k1'] mat `gamma_star' = `getb'[1,`k1'+1..`dim2'-1] } mat `beta_1' = J(`k1',1,1) forvalues one=1/`k1' { mat `beta_1'[`k1',1] = 1 } mat `diag1' = diag(`betaA'-`betaB') mat `diag2' = diag(`beta_star'-`betaB') mat `inv' = inv(`diag1') mat `omega_mat' = `diag2'*`inv' mat `omega_vec' = `omega_mat'*`beta_1' mat `omega_vec' = `omega_vec'' forvalues one=1/`k1' { if `one'==1 { local omega1 = `omega_vec'[1,1] local omega2 `omega1' } else if `one'>1 { local comma , local omega_`one' = `omega_vec'[1,`one'] local omega2 `omega2' `comma' `omega_`one'' } } local omega `omega2' if ("`regcmd'"=="zip") | ("`regcmd'"=="zinb") { mat `gamma_1' = J(`k2',1,1) forvalues one=1/`k2' { mat `gamma_1'[`k2',1] = 1 } mat `diag1_g' = diag(`gammaA'-`gammaB') mat `diag2_g' = diag(`gamma_star'-`gammaB') mat `inv_g' = inv(`diag1_g') mat `gamma_mat' = `diag2_g'*`inv_g' mat `gamma_vec' = `gamma_mat'*`gamma_1' mat `gamma_vec' = `gamma_vec'' forvalues one=1/`k2' { if `one'==1 { local gamma1 = `gamma_vec'[1,1] local gamma2 `gamma1' } else if `one'>1 { local comma , local gamma_`one' = `gamma_vec'[1,`one'] local gamma2 `gamma2' `comma' `gamma_`one'' } } local gamma `gamma2' } } * output of omega matrix input `out' = (`omega') mat `_O' = diag(`out') local dimension = colsof(`_O') if `dimension' == 1 { local w_noout = 0 local weight = `omega' } else if `dimension' != 1 { local w_noout = 1 } * calculate omega using nld_progomega if "`threshnum'" == "" { local threshnum = 0 } * nld_progomega nld_progomega, omega(`omega') dim1(`k1') dim2(`k2') * get omega matrix matrix `W' = r(W) * get matrix for gamma if ("`regcmd'"=="zip" | "`regcmd'" == "zinb") { mat `W_gamma' = r(W_gamma) } local noout = 0 } * create default matrix omega else if "`omega'" == "" { matrix `W' = I(`k1') * create default matrix gamma if ("`regcmd'"=="zip" | "`regcmd'" == "zinb") { mat `W_gamma' = I(`k2') } *suppress output local noout = 1 local w_noout = 1 } * counterfactual beta mat `I' = I(`k1') mat `beta_star' = `W'*`betaA'' + (`I'-`W')*`betaB'' mat `beta_star' = `beta_star'' * counterfactual gamma if ("`regcmd'"=="zip" | "`regcmd'" == "zinb") { mat `I_gamma' = I(`k2') mat `gamma_star' = `W_gamma'*`gammaA'' + (`I_gamma'-`W_gamma')*`gammaB'' mat `gamma_star' = `gamma_star'' } * mu if ("`regcmd'"=="ologit" | "`regcmd'" == "oprobit") { forvalues num = 1/`threshnum' { scalar mu`num'BA = mu`num'A scalar mu`num'AB = mu`num'A } } * counterfactual predictions qui gen double `c_predA' = 0 if `sampleA' == 1 qui gen double `c_predB' = 0 if `sampleB' == 1 qui gen double `c_predAB' = 0 if `sampleB' == 1 qui gen double `c_predBA' = 0 if `sampleA' == 1 if ("`regcmd'"=="zip" | "`regcmd'" == "zinb") { qui gen double `c_pred2A' = 0 if `sampleA' == 1 qui gen double `c_pred2B' = 0 if `sampleB' == 1 qui gen double `c_pred2AB' = 0 if `sampleB' == 1 qui gen double `c_pred2BA' = 0 if `sampleA' == 1 } local cnt = 1 tempvar const qui gen double `const' = 1 if ("`regcmd'"!="ologit" & "`regcmd'" != "oprobit") { local indvar2 `indvar' `const' } else if ("`regcmd'"=="ologit" | "`regcmd'" == "oprobit") { local indvar2 `indvar' } foreach var in `indvar2' { qui replace `c_predA' = `c_predA' + `betaA'[1,`cnt']*`var' if `sampleA' == 1 qui replace `c_predB' = `c_predB' + `betaB'[1,`cnt']*`var' if `sampleB' == 1 qui replace `c_predAB' = `c_predAB' + `beta_star'[1,`cnt']*`var' if `sampleB' == 1 qui replace `c_predBA' = `c_predBA' + `beta_star'[1,`cnt']*`var' if `sampleA' == 1 local cnt = `cnt'+1 } if ("`regcmd'"=="zip" | "`regcmd'" == "zinb") { local cnt2 = 1 local indvar3 `namesA' `const' foreach var in `indvar3' { qui replace `c_pred2A' = `c_pred2A' + `gammaA'[1,`cnt2']*`var' if `sampleA' == 1 qui replace `c_pred2B' = `c_pred2B' + `gammaB'[1,`cnt2']*`var' if `sampleB' == 1 qui replace `c_pred2AB' = `c_pred2AB' + `gamma_star'[1,`cnt2']*`var' if `sampleB' == 1 qui replace `c_pred2BA' = `c_pred2BA' + `gamma_star'[1,`cnt2']*`var' if `sampleA' == 1 local cnt2 = `cnt2'+1 } } * decomposition * compute conditional expected values if ("`regcmd'"=="intreg" | "`regcmd'"=="tobit" | "`regcmd'"=="truncreg" ) { // retrieve limits used in regression local llimit `ll' local ulimit `ul' if "`llimit'" == "" { local llimit . } if "`ulimit'" == "" { local ulimit . } tempvar ll ul nld_dcp_limits, regcmd(`regcmd') ll(`ll') ul(`ul') llimit(`llimit') ulimit(`ulimit') if ("`regcmd'"=="intreg" | "`regcmd'"=="tobit" ) { local DUMMY = 1 } else if ("`regcmd'"=="truncreg") { local DUMMY = 0 } foreach z in _ c_ { * decomposition depends on specified limits qui gen double ``z'valueA' = . qui gen double ``z'valueB' = . qui gen double ``z'valueAB' = . qui gen double ``z'valueBA' = . //////////////////////////////// // observations with no limits foreach X in A B { qui replace ``z'value`X'' = ``z'pred`X'' if `sample`X'' == 1 & (`ll'==.) & (`ul'==.) } qui replace ``z'valueAB' = ``z'predAB' if `sampleB' == 1 & (`ll'==.) & (`ul'==.) qui replace ``z'valueBA' = ``z'predBA' if `sampleA' == 1 & (`ll'==.) & (`ul'==.) ///////////////////////////// // observations with ll only * group A + B foreach X in A B { qui replace ``z'value`X'' = `DUMMY'*`ll'*normal((`ll'-``z'pred`X'')/`sigma`X'') + /// (1-normal((`ll'-``z'pred`X'')/`sigma`X''))*``z'pred`X''+`sigma`X''*normalden((`ll'-``z'pred`X'')/`sigma`X'') if `sample`X'' == 1 & (`ll'!=.) & (`ul'==.) } * AB qui replace ``z'valueAB' = `DUMMY'*`ll'*normal((`ll'-``z'predAB')/`sigmaA') + /// (1-normal((`ll'-``z'predAB')/`sigmaB'))*``z'predAB'+`sigmaB'*normalden((`ll'-``z'predAB')/`sigmaB') if `sampleB'==1 & (`ll'!=.) & (`ul'==.) * BA qui replace ``z'valueBA' = `DUMMY'*`ll'*normal((`ll'-``z'predBA')/`sigmaA') + /// (1-normal((`ll'-``z'predBA')/`sigmaA'))*``z'predBA'+`sigmaA'*normalden((`ll'-``z'predBA')/`sigmaA') if `sampleA'==1 & (`ll'!=.) & (`ul'==.) ///////////////////////////// // observations with ul only * group A + B foreach X in A B { qui replace ``z'value`X'' = `DUMMY'*`ul'*(1-normal((`ul'-``z'pred`X'')/`sigma`X'')) + /// normal((`ul'- ``z'pred`X'')/`sigma`X'')*``z'pred`X''-`sigma`X''*normalden((`ul'-``z'pred`X'')/`sigma`X'') if `sample`X''==1 & (`ll'==.) & (`ul'!=.) } * AB qui replace ``z'valueAB' = `DUMMY'*`ul'*(1-normal((`ul'-``z'predAB')/`sigmaB')) + /// normal((`ul'- ``z'predAB')/`sigmaB')*``z'predAB'-`sigmaB'*normalden((`ul'-``z'predAB')/`sigmaB') if `sampleB'== 1 & (`ll'==.) & (`ul'!=.) * BA qui replace ``z'valueBA' = `DUMMY'*`ul'*(1-normal((`ul'-``z'predBA')/`sigmaA')) + /// normal((`ul'- ``z'predBA')/`sigmaA')*``z'predBA'-`sigmaA'*normalden((`ul'-``z'predBA')/`sigmaA') if `sampleA'== 1 & (`ll'==.) & (`ul'!=.) /////////////////////////////// // observations with ll and ul * group A + B foreach X in A B { qui replace ``z'value`X'' = `DUMMY'*`ll'*normal((`ll'-``z'pred`X'')/`sigma`X'') + /// `DUMMY'*`ul'*(1-normal((`ul'-``z'pred`X'')/`sigma`X'')) + /// (normal((`ul'-``z'pred`X'')/`sigma`X'')-normal((`ll'-``z'pred`X'')/`sigma`X'')) * /// (``z'pred`X''+`sigma`X''*((normalden((`ll'-``z'pred`X'')/`sigma`X'') /// - normalden((`ul'-``z'pred`X'')/`sigma`X''))/( normal((`ul' /// - ``z'pred`X'')/`sigma`X'') - normal((`ll'-``z'pred`X'')/`sigma`X'')))) if `sample`X'' == 1 & (`ll'!=.) & (`ul'!=.) } * AB qui replace ``z'valueAB' = `DUMMY'*`ll'*normal((`ll'-``z'predAB')/`sigmaB') + /// `DUMMY'*`ul'*(1-normal((`ul'-``z'predAB')/`sigmaB')) + /// (normal((`ul'-``z'predAB')/`sigmaB')-normal((`ll'-``z'predAB')/`sigmaB')) * /// (``z'predAB'+`sigmaB'*((normalden((`ll'-``z'predAB')/`sigmaB') /// - normalden((`ul'-``z'predAB')/`sigmaB'))/( normal((`ul' /// - ``z'predAB')/`sigmaB') - normal((`ll'-``z'predAB')/`sigmaB')))) if `sampleB'== 1 & (`ll'!=.) & (`ul'!=.) * BA qui replace ``z'valueBA' = `DUMMY'*`ll'*normal((`ll'-``z'predBA')/`sigmaA') + /// `DUMMY'*`ul'*(1-normal((`ul'-``z'predBA')/`sigmaA')) + /// (normal((`ul'-``z'predBA')/`sigmaA')-normal((`ll'-``z'predBA')/`sigmaA')) * /// (``z'predBA'+`sigmaA'*((normalden((`ll'-``z'predBA')/`sigmaA') /// - normalden((`ul'-``z'predBA')/`sigmaA'))/( normal((`ul' /// - ``z'predBA')/`sigmaA') - normal((`ll'-``z'predBA')/`sigmaA')))) if `sampleA'== 1 & (`ll'!=.) & (`ul'!=.) // generating means foreach X in A B AB BA { qui su ``z'value`X'', meanonly scalar ``z'expval`X'' = r(mean) } } } else { if ("`regcmd'"!="tobit" & "`regcmd'"!="intreg" & "`regcmd'"!="truncreg") { foreach z in _ c_ { foreach X in A B AB BA { if ("`regcmd'"=="regress") { qui gen double ``z'value`X'' = ``z'pred`X'' } else if ("`regcmd'"=="poisson" | "`regcmd'"=="nbreg" | "`regcmd'"=="ztp" | "`regcmd'"=="ztnb") { qui gen double ``z'value`X'' = exp(``z'pred`X'') } else if ("`regcmd'"=="probit") { qui gen double ``z'value`X'' = normal(``z'pred`X'') } else if ("`regcmd'"=="logit") { qui gen double ``z'value`X'' = 1 / (1 + exp(-``z'pred`X'')) } else if ("`regcmd'"=="ologit") { if `threshnum' == 1 { qui gen double ``z'value`X'' = 1-(exp(mu1`X'-``z'pred`X'')/(1+exp(mu1`X'-``z'pred`X''))) } else if `threshnum' > 1 { qui gen double ``z'value`X'' = exp(mu1`X'-``z'pred`X'')/(1+exp(mu1`X'-``z'pred`X'')) - exp(-``z'pred`X'')/(1+exp(-``z'pred`X'')) forvalues _high = 2/`threshnum' { if `_high'==`threshnum' { local _low = `_high'-1 qui replace ``z'value`X'' = ``z'value`X'' + `_high'*(1-(exp(mu`_low'`X'-``z'pred`X'')/(1+exp(mu`_low'`X'-``z'pred`X'')))) } else if `_high'<`threshnum' { local _low = `_high'-1 qui replace ``z'value`X'' = ``z'value`X'' + `_high'*((exp(mu`_high'`X'-``z'pred`X'')/(1+exp(mu`_high'`X'-``z'pred`X''))) - (exp(mu`_low'`X'-``z'pred`X'')/(1+exp(mu`_low'`X'-``z'pred`X'')))) } } } } else if ("`regcmd'"=="oprobit") { if `threshnum' == 1 { qui gen double ``z'value`X'' = 1-normal(mu1`X'-``z'pred`X'') } else if `threshnum' > 1 { qui gen double ``z'value`X'' = normal(mu1`X'-``z'pred`X'') - normal(-``z'pred`X'') forvalues _high = 2/`threshnum' { if `_high'==`threshnum' { local _low = `_high'-1 qui replace ``z'value`X'' = ``z'value`X'' + `_high'*(1 - normal(mu`_low'`X'-``z'pred`X'')) } else if `_high'<`threshnum' { local _low = `_high'-1 qui replace ``z'value`X'' = ``z'value`X'' + `_high'*(normal(mu`_high'`X'-``z'pred`X'') - normal(mu`_low'`X'-``z'pred`X'')) } } } } else if ("`regcmd'"=="zip" | "`regcmd'"=="zinb") { qui gen double ``z'value`X'' = exp(``z'pred`X'')*(1 - (exp(``z'pred2`X'') / (1 + exp(``z'pred2`X'')))) } } } } if `noout' == 0 { foreach z in _ c_ { foreach X in A B AB BA { qui su ``z'value`X'', meanonly scalar ``z'expval`X'' = r(mean) } } } else if `noout' == 1 { foreach X in A B AB BA { qui su `_value`X'', meanonly scalar `_expval`X'' = r(mean) } } } ereturn clear // bootstrap without 'nodrop' possible (-> e(sample)) ////////////////////////////////////////////////////////////////////// // perform calculations with expected values and create nld returns // ////////////////////////////////////////////////////////////////////// scalar `raw' = `_expvalA' - `_expvalB' scalar nld_raw = `raw' * AB if "`threefold'" == "" { scalar nld_charAB = `_expvalA' - `_expvalAB' scalar nld_pcharAB = (`_expvalA' - `_expvalAB') / `raw' } else { scalar nld_charAB = `_expvalBA' - `_expvalB' scalar nld_pcharAB = (`_expvalBA' - `_expvalB') / `raw' scalar nld_intAB = `_expvalA' - `_expvalBA' - `_expvalAB' + `_expvalB' scalar nld_pintAB = (`_expvalA' - `_expvalBA' - `_expvalAB' + `_expvalB') / `raw' } scalar nld_coefAB = `_expvalAB' - `_expvalB' scalar nld_pcoefAB = (`_expvalAB' - `_expvalB') / `raw' * BA if "`threefold'" == "" { scalar nld_charBA = `_expvalBA' - `_expvalB' scalar nld_pcharBA = (`_expvalBA' - `_expvalB') / `raw' } else { scalar nld_charBA = `_expvalA' - `_expvalAB' scalar nld_pcharBA = (`_expvalA' - `_expvalAB') / `raw' scalar nld_intBA = `_expvalAB' - `_expvalB' - `_expvalA' + `_expvalBA' scalar nld_pintBA = (`_expvalAB' - `_expvalB' - `_expvalA' + `_expvalBA') / `raw' } scalar nld_coefBA = `_expvalA' - `_expvalBA' scalar nld_pcoefBA = (`_expvalA' - `_expvalBA') / `raw' if "`omega'" != "" { if `dimension' == 1 { scalar nld_wgt = `weight' } else { matrix nld_wgt = `W' } scalar nld_adv = `_expvalA' - `c_expvalBA' scalar nld_disadv = `c_expvalAB' - `_expvalB' scalar nld_prod = `c_expvalBA' - `c_expvalAB' scalar nld_padv = (`_expvalA' - `c_expvalBA') / `raw' scalar nld_pdisadv = (`c_expvalAB' - `_expvalB') / `raw' scalar nld_pprod = (`c_expvalBA' - `c_expvalAB') / `raw' } global nld_regcmd `regcmd' * number of observations for a - defined only once capture confirm scalar nld_obsA if _rc { scalar nld_obsA = `obsA' } * number of observations for b - defined only once capture confirm scalar nld_obsB if _rc { scalar nld_obsB = `obsB' } end program define nld_progomega, rclass syntax, omega(string) dim1(string) dim2(string) tempname inp W W_gamma * return weights for omega matrix input `inp' = (`omega') mat `W' = diag(`inp') local w = "`omega'" local dimw = colsof(`W') if `dimw' == 1 & `dimw' != `dim1' { mat `W' = I(`dim1')*`w' } else if `dimw' > 1 & `dimw' != `dim1' { di as error "ERROR: wrong number of weights in omega()" error 99999 } return matrix W = `W' * return weights for gamma if "`dim2'" != "0" { if `dimw' == 1 { mat `W_gamma' = I(`dim2')*`w' } else if `dimw' > 1 { mat `W_gamma' = I(`dim2') } return matrix W_gamma = `W_gamma' } end program define nld_parse_regcmd, rclass local before `0' local after : subinstr local before "svy:" "" if "`before'" != "`after'" { return local svy = "svy:" } local regcmd: word 1 of `after' return local regcmd `regcmd' return local rest: subinstr local after "`regcmd'" "" end program nld_dcp_limits syntax, regcmd(string) ll(string) ul(string) [llimit(string)] [ulimit(string)] qui gen `ll' = . qui gen `ul' = . if "`regcmd'" == "intreg" { if "`llimit'`ulimit'" == ".." { di as error "You have to specify ll() and/or ul() when working with intreg!" error 99999 } if "`llimit'" != "." { qui replace `ll' = `llimit' } if "`ulimit'" != "." { qui replace `ul' = `ulimit' } } else if "`regcmd'" == "tobit" { foreach xx in ll ul { capture confirm scalar e(`xx'opt) if !_rc { qui replace ``xx'' = e(`xx'opt) } } } else if "`regcmd'" == "truncreg" { foreach xx in ll ul { if "`e(`xx'opt)'" != "" { qui replace ``xx'' = `e(`xx'opt)' } } } end program nld_getcmd, rclass // "local cmds" holds all allowed commands #delimit ; local cmds regress tobit intreg truncreg poisson nbreg zip zinb ztp ztnb logit probit ologit oprobit ; #delimit cr * code which checks the given abbreviation args abbrev local abbrev = trim("`abbrev'") local length = length("`abbrev'") local matches = 0 foreach cmd of local cmds { local abbrecmd = substr("`cmd'", 1, `length') if "`abbrecmd'" == "`abbrev'" { local unabbrecmd = "`cmd'" local ++matches if "`abbrecmd'" == "`cmd'" { // if abbrecmd == cmd -> cmd must be the right command! local matches = 1 continue, break } } } if `matches' == 0 { di as error "<`abbrev'> is not supported!" error 9999 } if `matches' == 1 { return local cmd = "`unabbrecmd'" } else if `matches' > 1 { di as error "The given abbreviation <`abbrev'> is ambiguous!" error 9999 } end program define nld_parse_varlist, rclass args varlist model if "`model'" == "intreg" { local depvar1: word 1 of `varlist' local depvar2: word 2 of `varlist' local depvar `depvar1' `depvar2' } else { local depvar: word 1 of `varlist' } return local depvar "`depvar'" return local indvar: subinstr local varlist "`depvar' " "" end program define nld_create_bootstrap_nlds // scalars scalar nld_level = e(level) scalar nld_N_reps = e(N_reps) // matrices tempname level N_reps // scalars tempname mcoef mse mcin mcip mcib mresult // matrices matrix `mcoef' = e(b) matrix `mse' = e(se) matrix `mcin' = e(ci_normal) matrix `mcip' = e(ci_percentile) matrix `mcib' = e(ci_bc) local ncoefs: word count `0' matrix `mresult' = J(10,`ncoefs',.) matrix rownames `mresult' = coef se z p cin_ll cin_ul cip_ll cip_ul cib_ll cib_ul matrix colnames `mresult' = `0' matrix `mresult'[1,1] = `mcoef' matrix `mresult'[2,1] = `mse' forval i = 1 / `ncoefs' { matrix `mresult'[3,`i'] = `mcoef'[1, `i']/`mse'[1, `i'] matrix `mresult'[4,`i'] = 2*(1-normal(abs(`mresult'[3,`i']))) } matrix `mresult'[5,1] = `mcin' matrix `mresult'[7,1] = `mcip' matrix `mresult'[9,1] = `mcib' local n = 0 foreach exp of local 0 { local ++n scalar nld_`exp' = `mcoef'[1,`n'] } matrix nld_bootstrap = `mresult' end program define nld_setreturns, rclass syntax, [order] ////////////////////// // get all (nld_*)s // ////////////////////// local nld_scalars : all scalars "nld_*" local nld_scalars : subinstr local nld_scalars "nld_" "", all local nld_matrices : all matrices "nld_*" local nld_matrices : subinstr local nld_matrices "nld_" "", all local nld_globals : all globals "nld_*" local nld_globals : subinstr local nld_globals "nld_" "", all //////////////////// // order (nld_*)s // //////////////////// local return_order raw charAB coefAB intAB pcharAB pcoefAB pintAB charBA coefBA intBA pcharBA pcoefBA pintBA prod adv disadv pprod padv pdisadv obsA obsB N_reps level sigmaA sigmaB regcmd bootstrap wgt foreach return of local return_order { if `: list return in nld_scalars' { local ord_scalars `ord_scalars' `return' //note: a possible bug requires a reverse order of the returns! local nld_scalars : list nld_scalars - return } else if `: list return in nld_matrices' { local ord_matrices `return' `ord_matrices' local nld_matrices : list nld_matrices - return } else if `: list return in nld_globals' { local ord_globals `return' `globals' local nld_globals : list nld_globals - return } } local scalars `ord_scalars' `nld_scalars' //note: a possible bug requires a reverse order of the returns! local matrices `nld_matrices' `ord_matrices' local globals `nld_globals' `ord_globals' //////////////////////////////// // return (nld_*)s as returns // //////////////////////////////// return clear // scalars foreach scalar of local scalars { return scalar `scalar' = nld_`scalar' scalar drop nld_`scalar' } // matrices foreach matrix of local matrices { return matrix `matrix' = nld_`matrix' } // globals -> macros (locals) foreach global of local globals { return local `global' ${nld_`global'} global nld_`global' } end program define nld_output syntax, [bootstrap] if "`r(threefold)'" != "" { local threefold threefold } if "`r(omega)'" != "" { local omega omega } local col = 13 local hlen = 63 local space = "{dup 2: }" // space between "|"-line and first number local header = "`space'{ralign 9:Coef.}" if "`bootstrap'" == "" { local header = "`header'`space'{ralign 10:Percentage}" } else { local header = "`header'`space'{ralign 9:Std. Err.}`space'{ralign 7:z }`space'{ralign 5:P>|z|}`space'{ralign 23:[`r(level)'% Conf. Interval]}" } // // Begin output // di di as text "{col 52}{lalign 17:Number of obs (A)} = " as result %7.0g r(obsA) di as text "{col 52}{lalign 17:Number of obs (B)} = " as result %7.0g r(obsB) if "`bootstrap'" != "" { di as text "{col 52}{lalign 17:BS Replications} = " as result %7.0g r(N_reps) } di di as text "{hline `col'}{c -}{c TT}{hline `hlen'}" di as text "{ralign `col':Results} {c |}" "`header'" foreach xx in AB BA { if "`xx'" == "AB" { local x = 1 } else { local x = 0 } di in text "{hline `col'}{c -}{c +}{hline `hlen'}" di as result "{lalign `col': Omega = `x'} " as text "{c |}" nld_outputline, coef(char`xx') begin("{ralign `col':Char} {c |}") space(`space') `bootstrap' nld_outputline, coef(coef`xx') begin("{ralign `col':Coef} {c |}") space(`space') `bootstrap' if "`threefold'" != "" { nld_outputline, coef(int`xx') begin("{ralign `col':Int} {c |}") space(`space') `bootstrap' } } if "`omega'" != "" { di as text "{hline `col'}{c -}{c +}{hline `hlen'}" capture confirm scalar r(wgt) if !_rc { if r(wgt) < 0 { local wgt: di "Omega < 0" } else if r(wgt) > 1 { local wgt: di "Omega > 1" } else { local wgt: di "Omega = " %3.2f r(wgt) } di as result "{lalign `col': {stata return list wgt:`wgt'}} " as text "{c |}" } else { di as result "{lalign `col': {stata matrix list r(wgt):Omega = wgt}} " as text "{c |}" } nld_outputline, coef(prod) begin("{ralign `col':Prod} {c |}") space(`space') `bootstrap' nld_outputline, coef(adv) begin("{ralign `col':Adv} {c |}") space(`space') `bootstrap' nld_outputline, coef(disadv) begin("{ralign `col':Disadv} {c |}") space(`space') `bootstrap' } di as text "{hline `col'}{c -}{c +}{hline `hlen'}" nld_outputline, coef(raw) begin("{ralign `col': Raw} {c |}") space(`space') `bootstrap' di as text "{hline `col'}{c -}{c BT}{hline `hlen'}" end program define nld_outputline syntax, begin(string) coef(string) space(string) [bootstrap] local fmt1 = "%9.0g" // format of numbers local fmt2 = "%7.2f" // format of numbers local fmt3 = "%5.3f" // format of numbers di as text "`begin'`space'" _c if "`bootstrap'" == "" { di as result `fmt1' r(`coef') "`space'" as result `fmt1' r(`coef')/r(raw)*100 "%" } else { tempname output matrix `output' = r(bootstrap) matrix `output' = `output'[1..., "`coef'"] di as result `fmt1' `output'[1, 1] "`space'" _c di as result `fmt1' `output'[2, 1] "`space'" _c di as result `fmt2' `output'[3, 1] "`space'" _c di as result `fmt3' `output'[4, 1] "`space' `space'" _c di as result `fmt1' `output'[5, 1] "`space'" _c di as result `fmt1' `output'[6, 1] } end program define nld_dropnlds local todrop: all globals "nld_*" foreach global of local todrop { global `global' } local todrop: all scalars "nld_*" capture scalar drop`todrop' local todrop: all matrices "nld_*" capture matrix drop`todrop' end