σ StatsDoge Causal inference workflows
9
Workflow·4 steps

Two-stage difference-in-differences (did2s)

Source did2s — Butts & Gardner
Summary by StatsDoge

Gardner's 2-stage estimator for staggered DiD: residualize on the untreated, then estimate the event study — fast and timing-robust.

1

Input · what goes in

A staggered panel: unit id, period, treatment indicator, relative event time.

Show data format & exampleHide example

Format — one row per (unit, period).

 id  year  treat  rel_year   y
  1  2003      0       -2    4.0
  1  2005      1        0    5.2
  2  2003      0       NA    3.9
2

Pipeline · the recipe

↑ Click any step in the diagram to read its logic, code, assumptions & discussion.

1
Data prep

Staggered panel + relative event time

Data preparation — shapes the raw inputs into what the estimator expects.

What happens here

Unit × period; treatment indicator and event time relative to first treatment.

Reads from the input data Feeds into #2
Key code
# id · year · treat · rel_year · y
Discussion on this step (0)
  • No comments on this step yet — be the first.
2
Estimation

[did2s] Two-stage difference-in-differences

The core estimate — where the causal quantity itself is computed.

What happens here

Two-stage estimation: FE on untreated, then residuals on treatment.

Formula
ilde Y_{it}=Y_{it}-\hat\alpha_i-\hat\lambda_t,\quad ilde Y_{it}= extstyle\sum_eeta_e D^e_{it}+\varepsilon_{it}
The estimator

Two-stage difference-in-differences — Gardner's two-stage estimator: remove unit/time fixed effects from untreated obs, then regress residuals on treatment — robust to heterogeneous timing.

Reads from #1 Feeds into #3#4
Key code
did2s(df, yname="y", first_stage=~0|id+year, second_stage=~i(rel_year), treatment="treat", cluster_var="id")
Discussion on this step (0)
  • No comments on this step yet — be the first.
3
Robustness check

Compare to TWFE / CS

A robustness check — does the headline result survive a different lens?

What happens here

Overlay against naive TWFE and Callaway-Sant'Anna to confirm agreement.

Reads from #2 Feeds into #4
Key code
# plot did2s vs TWFE vs CS event-study

Reference / docs ↗

Discussion on this step (0)
  • No comments on this step yet — be the first.
4
Reporting

Event-study plot

Reporting — turn the numbers into a figure or table a reader can act on.

What happens here

Plot the dynamic effects with confidence bands.

Reads from #2#3 Feeds into the final output
Key code
iplot(est)
Discussion on this step (0)
  • No comments on this step yet — be the first.
3

Output · what you get 3 figures

did2s event-study estimates of the dynamic ATT.
Fig 1did2s event-study estimates of the dynamic ATT.
Two-stage estimates under heterogeneous treatment effects.
Fig 2Two-stage estimates under heterogeneous treatment effects.
did2s vs TWFE vs Callaway–Sant'Anna — the estimators side by side.
Fig 3did2s vs TWFE vs Callaway–Sant'Anna — the estimators side by side.

Figures reproduced from did2s — Butts & Gardner — unofficial community showcase; all credit to the original authors.

The did2s vignette. A lightweight alternative to Callaway-Sant'Anna for staggered designs. Unofficial summary.

Discussion (2)

  • 2

    Gardner's 2-stage trick is elegant: residualize on the untreated, then the second stage is just OLS. Fast on huge panels.

    2

    And it lines up with Callaway-Sant'Anna in practice — nice to show both agree.

  • 3

    did2s + fixest under the hood = blazing. My default for big staggered panels now.