*! version 1.0.0 26jan2026 program define ate_pct, rclass version 14.0 syntax varlist(min=1) [if] , [truew groupsize(numlist)] // Group indicator variables (d_i^g) local groupvars `varlist' local G: word count `groupvars' // check if there is e-class estimation. capture confirm matrix e(b) if (_rc) { di as error "ate_pct requires a preceding e-class estimation (with e(b), e(V), and e(sample))." exit 301 } capture confirm matrix e(V) if (_rc) { di as error "Missing e(V) from the preceding estimation." exit 301 } // Estimation sample from last e-class estimation tempvar touse marksample touse * restrict further to the estimation sample qui replace `touse' = 0 if e(sample) == 0 // Pull coefficient vector and vcov from last estimation tempname beta vcov N matrix `beta' = e(b) matrix `vcov' = e(V) scalar `N' = e(N) // Prepare tau, weights, Sigma_tau, Sigma_w tempname tau wgt Sigma_tau Sigma_w matrix `tau' = J(`G', 1, .) matrix `Sigma_tau' = J(`G', `G', 0) // Extract tau and Sigma_tau for group dummies forvalues g = 1/`G' { local dvar: word `g' of `groupvars' local col = colnumb(`beta', "`dvar'") if (`col' <= 0) { di as error "Group variable `dvar' not found in regression!" exit 198 } matrix `tau'[`g', 1] = `beta'[1, `col'] forvalues h = 1/`G' { local dvar2: word `h' of `groupvars' local col2 = colnumb(`beta', "`dvar2'") matrix `Sigma_tau'[`g', `h'] = `vcov'[`col', `col2'] } } // ------------------------------------------------------------ // Group sizes and weights // If option groupsize() is provided: treat it as N_g (group sizes) // Otherwise: count N_g from group indicators within e(sample) // ------------------------------------------------------------ tempname N_g N_s p_s matrix `N_g' = J(`G', 1, .) if ("`groupsize'" != "") { // Validate length of supplied numlist equals number of groups local nw : word count `groupsize' if (`nw' != `G') { di as error "Option groupsize() must contain exactly `G' numbers (one N_g per group, in the same order as the group vars)." exit 198 } // Fill N_g from the provided list forvalues g = 1/`G' { local ng_val : word `g' of `groupsize' if (real("`ng_val'") <= 0) { di as error "All elements in groupsize() must be > 0. Found groupsize[`g'] = `ng_val'." exit 198 } matrix `N_g'[`g', 1] = real("`ng_val'") } // N_s is the sum of supplied group sizes matrix define __ones = J(`G',1,1) matrix __sumn =__ones' * `N_g' // 1x1 scalar `N_s' = __sumn[1,1] scalar `p_s' = `N_s'/`N' matrix drop __ones __sumn } else { // Compute s_i = sum_g d_i^g tempvar s_i qui gen `s_i' = 0 foreach dvar of varlist `groupvars' { quietly count if `dvar'!= 0 & `dvar'!= 1 & `touse' if (r(N) > 0) { di as error "Group indicators must be 0/1." exit 198 } qui replace `s_i' = `s_i' + `dvar' } // Check if group dummies are mutually exclusive. quietly count if `s_i' > 1 & `touse' if (r(N) > 0) { di as error "Group indicators must be mutually exclusive within the target sample (found observations with multiple groups)." exit 198 } // Count group sizes within estimation sample forvalues g = 1/`G' { local dvar: word `g' of `groupvars' quietly count if `dvar' == 1 & `touse' if (r(N) == 0) { di as error "Group `dvar' has no observations in the target sample." exit 198 } matrix `N_g'[`g', 1] = r(N) } quietly count if `s_i' == 1 & `touse' scalar `N_s' = r(N) scalar `p_s' = `N_s'/`N' } matrix `wgt' = `N_g' * (1/`N_s') // Sigma_w tempname diag_w ww matrix `diag_w' = diag(`wgt') matrix `ww' = `wgt' * `wgt'' if ("`truew'" == "") { if (`p_s' <= 0) { di as error "p_s <= 0; cannot compute Sigma_w." exit 2001 } matrix `Sigma_w' = (1/`N') * (1/`p_s') * (`diag_w' - `ww') } else { matrix `Sigma_w' = J(`G', `G', 0) } // If truew is not enabled, display how weights are formed if ("`truew'" == "") { di as text "Note: weights are estimated using N_T =" %12.0f `N_s' " observations (p_T = " %9.6f `p_s' "). } // Core calculations in Mata (writes to r(b), r(V), r(delta), r(Sigma_delta)) mata: calc_basic("`tau'","`wgt'","`Sigma_tau'","`Sigma_w'") // Grab Mata results tempname b V delta Sigma_delta matrix `b' = r(b) matrix `V' = r(V) matrix `delta' = r(delta) matrix `Sigma_delta' = r(Sigma_delta) // Label results matname `b' taubar rho_a rho_b, explicit c(.) matname `V' taubar rho_a rho_b, explicit // ----------------------------- // Store results in r() // ----------------------------- return clear return local cmd "ate_pct" return scalar N = `N' return scalar N_T = `N_s' return scalar p_T = `p_s' return matrix b = `b' return matrix V = `V' return matrix delta = `delta' return matrix Sigma_delta = `Sigma_delta' // Also return underlying pieces (optional but handy) return matrix tau = `tau' return matrix w = `wgt' return matrix Sigma_tau = `Sigma_tau' return matrix Sigma_w = `Sigma_w' // ----------------------------- // Display results as a table // ----------------------------- tempname se z pval lb ub matrix `se' = J(1, colsof(r(b)), .) matrix `z' = J(1, colsof(r(b)), .) matrix `pval' = J(1, colsof(r(b)), .) matrix `lb' = J(1, colsof(r(b)), .) matrix `ub' = J(1, colsof(r(b)), .) scalar level = c(level) scalar zalpha = invnormal(1 - (100 - level)/200) forvalues i = 1/`=colsof(r(b))' { matrix `se'[1,`i'] = sqrt(r(V)[`i',`i']) matrix `z'[1,`i'] = r(b)[1,`i'] / `se'[1,`i'] matrix `pval'[1,`i'] = 2 * (1 - normal(abs(`z'[1,`i']))) matrix `lb'[1,`i'] = r(b)[1,`i'] - zalpha * `se'[1,`i'] matrix `ub'[1,`i'] = r(b)[1,`i'] + zalpha * `se'[1,`i'] } // Display table di as text _newline "ATE in Percentage Points" di as text "-----------------------------------------------------------------------------------------" di as text %12s "Parameter" %12s "Estimate" %14s "Std. Err." %8s "z" %14s "P>|z|" /// %6s "[" %3.0f level "% conf." %8s "interval]" di as text "-----------------------------------------------------------------------------------------" local names "taubar rho_a rho_b" forvalues i = 1/`=colsof(r(b))' { local name : word `i' of `names' di as result %12s "`name'" /// %12.4f r(b)[1,`i'] /// %12.4f `se'[1,`i'] /// %12.4f `z'[1,`i'] /// %12.4f `pval'[1,`i'] /// %12.4f `lb'[1,`i'] /// %12.4f `ub'[1,`i'] } di as text "-----------------------------------------------------------------------------------------" end mata: void calc_basic(string scalar tau_name, string scalar w_name, string scalar Sigma_tau_name, string scalar Sigma_w_name) { real matrix tau, w, Sigma_tau, Sigma_w, Sigma_eta real scalar taubar, Var_taubar, rho_a, Var_rho_a, rho_b, Var_b real matrix expeta0, b, V, se real scalar G tau = st_matrix(tau_name) w = st_matrix(w_name) Sigma_w = st_matrix(Sigma_w_name) Sigma_tau = st_matrix(Sigma_tau_name) G = rows(tau) expeta0 = w :* exp(tau) Sigma_eta = diag(1:/w) * Sigma_w * diag(1:/w) + Sigma_tau taubar = (w'*tau)[1,1] Var_taubar = (w'*Sigma_tau*w)[1,1] + (tau'*Sigma_w*tau)[1,1] rho_a = exp(taubar) - 1 Var_rho_a = (exp(taubar))^2 * Var_taubar rho_b = sum(w :* exp(tau)) - 1 Var_b = expeta0' * Sigma_eta * expeta0 b = (taubar, rho_a, rho_b) se = (sqrt(Var_taubar), sqrt(Var_rho_a), sqrt(Var_b)) V = diag(se:^2) st_rclear() st_matrix("r(b)", b) st_matrix("r(V)", V) st_matrix("r(delta)", (tau \ w)) st_matrix("r(Sigma_delta)", blockdiag(Sigma_tau, Sigma_w)) } end