Skip to contents

Native feTR weight diagnostic: the decomposition of the two-way fixed-effects DiD estimand into the weighted average of the \(N \times T\) unit-time ATEs. Each treated cell's weight is proportional to its residual from regressing the treatment on unit and time fixed effects, normalized over treated cells. Use this to quantify how many of the implicit comparisons receive negative weight, which is the canonical diagnostic for whether a TWFE specification can be interpreted as a convex combination of treatment effects. Reproduces TwoWayFEWeights::twowayfeweights(type = "feTR") weights to machine precision (see tests/cross/).

Usage

morie_did_twoway_fe_weights(
  panel,
  group,
  time,
  treatment,
  outcome = NULL,
  type = "feTR",
  ...
)

Arguments

panel

A long-format balanced (or near-balanced) panel data.frame.

group

Name of the unit / group identifier column.

time

Name of the time period column.

treatment

Name of the binary or continuous treatment column.

outcome

Optional outcome column; the feTR weights do not depend on the outcome values, so it may be NULL.

type

Weight type; only "feTR" (feasible TR weights, the default and the canonical diagnostic) is supported natively.

...

Ignored; retained for back-compat.

Value

An S3 list of class morie_did_twfe_diagnostics with elements n_negative_weights, sum_weights, sum_negative_weights, share_negative_weights, method, and raw (a data frame with one row per (group, time) cell and its weight).

References

de Chaisemartin, C., & D'Haultfoeuille, X. (2020). Two-way fixed effects estimators with heterogeneous treatment effects. American Economic Review, 110(9), 2964–2996.

Examples

set.seed(11)
df <- expand.grid(unit = 1:60, time = 1:8)
df$treat_time <- ifelse(df$unit <= 30, sample(c(3, 5), 1), Inf)
df$treat_time <- ifelse(df$unit <= 15, 3, ifelse(df$unit <= 30, 5, Inf))
df$d <- as.integer(df$time >= df$treat_time)
df$y <- 0.5 * df$time + 1.5 * df$d + rnorm(nrow(df), sd = 0.5)
out <- morie_did_twoway_fe_weights(df, "unit", "time", "d")
c(out$sum_weights, out$n_negative_weights)
#> [1] 1 0