moderndid.aggte#
- moderndid.aggte(MP, type='group', balance_e=None, min_e=-inf, max_e=inf, na_rm=False, boot=None, biters=None, cband=None, alp=None, clustervars=None, random_state=None)[source]#
Aggregate group-time average treatment effects.
Takes the full set of group-time average treatment effects from
att_gtand aggregates them into interpretable summary measures, following Callaway and Sant’Anna (2021) [1]. Different aggregation schemes answer different policy questions about treatment effect heterogeneity.Let \(\mathcal{G}\) denote the set of treatment groups, \(\mathcal{T}\) the final time period, \(G\) the random variable for treatment timing, and \(ATT(g,t)\) the group-time average treatment effect for group \(g\) at time \(t\).
The event-study or dynamic aggregation reveals how effects evolve with exposure time \(e = t - g\). The event-study parameter averages effects across groups observed \(e\) periods after treatment
\[\theta_{es}(e) = \sum_{g \in \mathcal{G}} \mathbf{1}\{g + e \le \mathcal{T}\} P(G = g \mid G + e \le \mathcal{T}) \, ATT(g, g + e).\]Group-specific aggregation averages effects over time for each treatment cohort \(\tilde{g}\), revealing whether early versus late adopters experience different effects
\[\theta_{sel}(\tilde{g}) = \frac{1}{\mathcal{T} - \tilde{g} + 1} \sum_{t=\tilde{g}}^{\mathcal{T}} ATT(\tilde{g}, t).\]Calendar-time aggregation averages across treated groups within each period \(\tilde{t}\), showing how effects vary with time-specific factors
\[\theta_{c}(\tilde{t}) = \sum_{g \in \mathcal{G}} \mathbf{1}\{\tilde{t} \ge g\} P(G = g \mid G \le \tilde{t}) \, ATT(g, \tilde{t}).\]The simple or overall aggregation provides a single summary measure by weighting group-specific effects by the distribution of treatment timing
\[\theta_{sel}^O = \sum_{g \in \mathcal{G}} \theta_{sel}(g) \, P(G = g \mid G \le \mathcal{T}).\]- Parameters:
- MP
MPResult An MP object (i.e., the results of the att_gt() method).
- type{‘simple’, ‘dynamic’, ‘group’, ‘calendar’}, default=’group’
Which type of aggregated treatment effect parameter to compute:
‘simple’: Computes a weighted average of all group-time average treatment effects with weights proportional to group size.
‘dynamic’: Computes average effects across different lengths of exposure to the treatment (similar to an event study).
‘group’: Computes average treatment effects across different groups.
‘calendar’: Computes average treatment effects across different time periods.
- balance_e
int, optional If set (and if one computes dynamic effects), it balances the sample with respect to event time. For example, if balance_e=2, aggte will drop groups that are not exposed to treatment for at least three periods (the initial period when e=0 as well as the next two periods when e=1 and e=2). This ensures that the composition of groups does not change when event time changes.
- min_e
float, default=-inf For event studies, this is the smallest event time to compute dynamic effects for. By default, min_e = -Inf so that effects at all lengths of exposure are computed.
- max_e
float, default=inf For event studies, this is the largest event time to compute dynamic effects for. By default, max_e = Inf so that effects at all lengths of exposure are computed.
- na_rmbool, default=False
Logical value if we are to remove missing values from analyses.
- bootbool, optional
Boolean for whether or not to compute standard errors using the multiplier bootstrap. If standard errors are clustered, then one must set boot=True. Default is value set in the MP object. If boot is False, then analytical standard errors are reported.
- biters
int, optional The number of bootstrap iterations to use. The default is the value set in the MP object, and this is only applicable if boot=True.
- cbandbool, optional
Boolean for whether or not to compute a uniform confidence band that covers all of the group-time average treatment effects with fixed probability 1-alp. In order to compute uniform confidence bands, boot must also be set to True. The default is the value set in the MP object.
- alp
float, optional The significance level, default is value set in the MP object.
- clustervars
list[str], optional A vector of variables to cluster on. At most, there can be two variables (otherwise will throw an error) and one of these must be the same as idname which allows for clustering at the individual level. Default is the variables set in the MP object.
- random_state
int,Generator, optional Controls the randomness of the bootstrap. Pass an int for reproducible results across multiple function calls. Can also accept a NumPy
Generatorinstance.
- MP
- Returns:
AGGTEResultAn AGGTEobj object that holds the results from the aggregation.
See also
att_gtCompute group-time average treatment effects.
References
[1]Callaway, B., & Sant’Anna, P. H. (2021). Difference-in-differences with multiple time periods. Journal of Econometrics, 225(2), 200-230. https://doi.org/10.1016/j.jeconom.2020.12.001
Examples
First, we compute group-time average treatment effects using the
att_gtfunction:In [1]: import numpy as np ...: from moderndid import att_gt, aggte, load_mpdta ...: ...: df = load_mpdta() ...: ...: # Compute group-time ATTs ...: att_gt_result = att_gt( ...: data=df, ...: yname="lemp", ...: tname="year", ...: gname="first.treat", ...: idname="countyreal", ...: est_method="dr", ...: boot=False ...: ) ...:
Now we can aggregate these group-time effects in different ways. The “simple” aggregation computes an overall ATT by taking a weighted average of all group-time ATTs:
In [2]: # Simple aggregation - overall ATT ...: simple_agg = aggte(MP=att_gt_result, type="simple") ...: print(simple_agg) ...: ============================================================================== Aggregate Treatment Effects ============================================================================== Overall ATT: ┌─────────┬────────────┬────────────────────────┐ │ ATT │ Std. Error │ [95% Conf. Interval] │ ├─────────┼────────────┼────────────────────────┤ │ -0.0400 │ 0.0120 │ [ -0.0635, -0.0164] * │ └─────────┴────────────┴────────────────────────┘ ------------------------------------------------------------------------------ Signif. codes: '*' confidence band does not cover 0 ------------------------------------------------------------------------------ Data Info ------------------------------------------------------------------------------ Control Group: Never Treated Anticipation Periods: 0 ------------------------------------------------------------------------------ Estimation Details ------------------------------------------------------------------------------ Estimation Method: Doubly Robust ------------------------------------------------------------------------------ Inference ------------------------------------------------------------------------------ Significance level: 0.05 Analytical standard errors ============================================================================== Reference: Callaway and Sant'Anna (2021)
The “group” aggregation computes average treatment effects separately for each treatment cohort (units first treated in the same period):
In [3]: # Group aggregation - ATT by treatment cohort ...: group_agg = aggte(MP=att_gt_result, type="group") ...: print(group_agg) ...: ============================================================================== Aggregate Treatment Effects (Group/Cohort) ============================================================================== Overall summary of ATT's based on group/cohort aggregation: ┌─────────┬────────────┬────────────────────────┐ │ ATT │ Std. Error │ [95% Conf. Interval] │ ├─────────┼────────────┼────────────────────────┤ │ -0.0310 │ 0.0124 │ [ -0.0554, -0.0066] * │ └─────────┴────────────┴────────────────────────┘ Group Effects: ┌───────┬──────────┬────────────┬────────────────────────────┐ │ Group │ Estimate │ Std. Error │ [95% Pointwise Conf. Band] │ ├───────┼──────────┼────────────┼────────────────────────────┤ │ 2004 │ -0.0797 │ 0.0264 │ [-0.1409, -0.0186] * │ │ 2006 │ -0.0229 │ 0.0167 │ [-0.0616, 0.0158] │ │ 2007 │ -0.0261 │ 0.0167 │ [-0.0647, 0.0125] │ └───────┴──────────┴────────────┴────────────────────────────┘ ------------------------------------------------------------------------------ Signif. codes: '*' confidence band does not cover 0 ------------------------------------------------------------------------------ Data Info ------------------------------------------------------------------------------ Control Group: Never Treated Anticipation Periods: 0 ------------------------------------------------------------------------------ Estimation Details ------------------------------------------------------------------------------ Estimation Method: Doubly Robust ------------------------------------------------------------------------------ Inference ------------------------------------------------------------------------------ Significance level: 0.05 Analytical standard errors ============================================================================== Reference: Callaway and Sant'Anna (2021)
The “dynamic” aggregation creates an event study, showing how treatment effects evolve relative to the treatment start date:
In [4]: # Dynamic aggregation - event study ...: dynamic_agg = aggte(MP=att_gt_result, type="dynamic") ...: print(dynamic_agg) ...: ============================================================================== Aggregate Treatment Effects (Event Study) ============================================================================== Overall summary of ATT's based on event-study/dynamic aggregation: ┌─────────┬────────────┬────────────────────────┐ │ ATT │ Std. Error │ [95% Conf. Interval] │ ├─────────┼────────────┼────────────────────────┤ │ -0.0772 │ 0.0200 │ [ -0.1164, -0.0381] * │ └─────────┴────────────┴────────────────────────┘ Dynamic Effects: ┌────────────┬──────────┬────────────┬────────────────────────────┐ │ Event time │ Estimate │ Std. Error │ [95% Pointwise Conf. Band] │ ├────────────┼──────────┼────────────┼────────────────────────────┤ │ -3 │ 0.0305 │ 0.0150 │ [-0.0090, 0.0700] │ │ -2 │ -0.0006 │ 0.0133 │ [-0.0355, 0.0344] │ │ -1 │ -0.0245 │ 0.0142 │ [-0.0619, 0.0130] │ │ 0 │ -0.0199 │ 0.0118 │ [-0.0510, 0.0112] │ │ 1 │ -0.0510 │ 0.0169 │ [-0.0954, -0.0065] * │ │ 2 │ -0.1373 │ 0.0364 │ [-0.2331, -0.0414] * │ │ 3 │ -0.1008 │ 0.0344 │ [-0.1912, -0.0105] * │ └────────────┴──────────┴────────────┴────────────────────────────┘ ------------------------------------------------------------------------------ Signif. codes: '*' confidence band does not cover 0 ------------------------------------------------------------------------------ Data Info ------------------------------------------------------------------------------ Control Group: Never Treated Anticipation Periods: 0 ------------------------------------------------------------------------------ Estimation Details ------------------------------------------------------------------------------ Estimation Method: Doubly Robust ------------------------------------------------------------------------------ Inference ------------------------------------------------------------------------------ Significance level: 0.05 Analytical standard errors ============================================================================== Reference: Callaway and Sant'Anna (2021)
We can also limit the event study to specific event times:
In [5]: # Dynamic effects from 2 periods before to 2 periods after treatment ...: dynamic_limited = aggte( ...: MP=att_gt_result, ...: type="dynamic", ...: min_e=-2, ...: max_e=2 ...: ) ...: print(dynamic_limited) ...: ============================================================================== Aggregate Treatment Effects (Event Study) ============================================================================== Overall summary of ATT's based on event-study/dynamic aggregation: ┌─────────┬────────────┬────────────────────────┐ │ ATT │ Std. Error │ [95% Conf. Interval] │ ├─────────┼────────────┼────────────────────────┤ │ -0.0694 │ 0.0173 │ [ -0.1032, -0.0355] * │ └─────────┴────────────┴────────────────────────┘ Dynamic Effects: ┌────────────┬──────────┬────────────┬────────────────────────────┐ │ Event time │ Estimate │ Std. Error │ [95% Pointwise Conf. Band] │ ├────────────┼──────────┼────────────┼────────────────────────────┤ │ -2 │ -0.0006 │ 0.0133 │ [-0.0334, 0.0323] │ │ -1 │ -0.0245 │ 0.0142 │ [-0.0596, 0.0107] │ │ 0 │ -0.0199 │ 0.0118 │ [-0.0492, 0.0093] │ │ 1 │ -0.0510 │ 0.0169 │ [-0.0927, -0.0092] * │ │ 2 │ -0.1373 │ 0.0364 │ [-0.2273, -0.0472] * │ └────────────┴──────────┴────────────┴────────────────────────────┘ ------------------------------------------------------------------------------ Signif. codes: '*' confidence band does not cover 0 ------------------------------------------------------------------------------ Data Info ------------------------------------------------------------------------------ Control Group: Never Treated Anticipation Periods: 0 ------------------------------------------------------------------------------ Estimation Details ------------------------------------------------------------------------------ Estimation Method: Doubly Robust ------------------------------------------------------------------------------ Inference ------------------------------------------------------------------------------ Significance level: 0.05 Analytical standard errors ============================================================================== Reference: Callaway and Sant'Anna (2021)
The “calendar” aggregation computes average treatment effects by calendar time period:
In [6]: # Calendar time aggregation - ATT by year ...: calendar_agg = aggte(MP=att_gt_result, type="calendar") ...: print(calendar_agg) ...: ============================================================================== Aggregate Treatment Effects (Calendar Time) ============================================================================== Overall summary of ATT's based on calendar time aggregation: ┌─────────┬────────────┬────────────────────────┐ │ ATT │ Std. Error │ [95% Conf. Interval] │ ├─────────┼────────────┼────────────────────────┤ │ -0.0417 │ 0.0160 │ [ -0.0730, -0.0104] * │ └─────────┴────────────┴────────────────────────┘ Time Effects: ┌──────┬──────────┬────────────┬────────────────────────────┐ │ Time │ Estimate │ Std. Error │ [95% Pointwise Conf. Band] │ ├──────┼──────────┼────────────┼────────────────────────────┤ │ 2004 │ -0.0105 │ 0.0233 │ [-0.0669, 0.0459] │ │ 2005 │ -0.0704 │ 0.0310 │ [-0.1456, 0.0047] │ │ 2006 │ -0.0488 │ 0.0201 │ [-0.0976, 0.0000] │ │ 2007 │ -0.0371 │ 0.0137 │ [-0.0704, -0.0037] * │ └──────┴──────────┴────────────┴────────────────────────────┘ ------------------------------------------------------------------------------ Signif. codes: '*' confidence band does not cover 0 ------------------------------------------------------------------------------ Data Info ------------------------------------------------------------------------------ Control Group: Never Treated Anticipation Periods: 0 ------------------------------------------------------------------------------ Estimation Details ------------------------------------------------------------------------------ Estimation Method: Doubly Robust ------------------------------------------------------------------------------ Inference ------------------------------------------------------------------------------ Significance level: 0.05 Analytical standard errors ============================================================================== Reference: Callaway and Sant'Anna (2021)