Skip to contents

Collapses the Goodman-Bacon (2021, Theorem 1, eqs. 7-9) decomposition to its three comparison types: a timing cohort against never-treated units, an earlier cohort against a later one before the later adopts, and a later cohort against an already-treated earlier one – the forbidden comparison whose weight is how a TWFE coefficient can land below every clean comparison when effects grow over time. Reports total weight, weighted-average 2x2 estimate and contribution per type; the three contributions sum back to the TWFE coefficient and the weights sum to 1, both computed and reported rather than assumed.

Usage

Gbtcom(data, outcome, treatment, unit, time)

Arguments

data

Long-format balanced panel data frame.

outcome

Name of the outcome column.

treatment

Name of the absorbing 0/1 treatment column.

unit

Name of the unit identifier column.

time

Name of the period column.

Value

List with estimate (TWFE coefficient), weight, mean_beta and contribution (named vectors over the three types), weight_sum, identity_residual, forbidden_weight and n_components_by_type.

Details

Classification rule (identical to the Python arm): a component with an infinite control cohort is treated-vs-never; otherwise a treated cohort adopting before its control cohort is early-vs-late, and one adopting after its (already treated) control cohort is late-vs-early.

References

Goodman-Bacon, A. (2021). Difference-in-differences with variation in treatment timing. Journal of Econometrics, 225(2), 254-277. doi:10.1016/j.jeconom.2021.03.014. Implemented from Theorem 1 and eqs. (7)-(9) of NBER Working Paper 25018;

Examples

u <- rep(1:9, each = 8L)
tt <- rep(1:8, times = 9L)
g <- rep(c(3, 3, 3, 5, 5, 5, Inf, Inf, Inf), each = 8L)
rel <- ifelse(is.finite(g), pmax(0, tt - g), 0)
y <- u * 0.3 + tt * 0.2 + ifelse(tt >= g, 1 + 0.5 * rel, 0)
d <- data.frame(y = y, d = as.numeric(tt >= g), unit = u, time = tt)
out <- Gbtcom(d, "y", "d", "unit", "time")
round(out$weight[["treated vs never-treated"]], 10)
#> [1] 0.7