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_gt and 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:
MPMPResult

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_eint, 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_efloat, 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_efloat, 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.

bitersint, 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.

alpfloat, optional

The significance level, default is value set in the MP object.

clustervarslist[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_stateint, Generator, optional

Controls the randomness of the bootstrap. Pass an int for reproducible results across multiple function calls. Can also accept a NumPy Generator instance.

Returns:
AGGTEResult

An AGGTEobj object that holds the results from the aggregation.

See also

att_gt

Compute 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_gt function:

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)