Formula: the dynamic two-way fixed effects specification
y_it = alpha_i + lambda_t + sum_{e != ref} mu_e 1{t - g_i = e} + eps
where g_i is unit i's treatment cohort and e = t - g_i is event time. One event-time indicator must be dropped for identification against the unit and period effects; e = ref (conventionally -1) is omitted, so every mu_e is read relative to it. Never-treated units (cohort NA or infinite) enter only through alpha_i and lambda_t and act as a clean control group.
Arguments
- y
Outcome, one entry per unit-period.
- D
Treatment indicator (carried for reference; the event dummies are built from
cohortandtime).- unit, time
Unit and period labels.
- cohort
First treated period per observation; NA or Inf marks a never-treated unit.
- max_lead, max_lag
Truncate the window to [-max_lead, max_lag].
- ref
Omitted event time.
Details
CAVEAT, not a defect of the code: with heterogeneous, dynamic treatment effects these mu_e are contaminated – weighted sums of cohort-specific effects at OTHER relative periods, with weights that can be negative. Sun & Abraham (2021) prove this and give the interaction-weighted alternative.
References
Sun & Abraham (2021), Journal of Econometrics 225(2):175-199, doi:10.1016/j.jeconom.2020.09.006; Borusyak & Jaravel (2017), "Revisiting Event Study Designs", working paper.
Examples
set.seed(8)
units <- 1:30; periods <- 1:6
d <- expand.grid(time = periods, unit = units)
cohort <- rep(c(4, Inf), each = 15)[d$unit]
d$D <- as.integer(d$time >= cohort)
d$y <- rnorm(nrow(d)) + 2 * d$D + d$unit / 10
e <- Evstud(d$y, d$D, d$unit, d$time, cohort)
round(e$coef, 2)
#> [1] 1.04 0.49 1.15 2.04 2.18
