Skip to contents

Native Callaway-Sant'Anna (2021) estimator. For each cohort \(g\) and each period t, estimates \(\mathrm{ATT}(g, t)\) with the Sant'Anna-Zhao (2020) panel estimators (doubly robust, IPW, or outcome regression) on the two-period comparison against the last pre-treatment base period ("varying" base period, matching did::att_gt's default). Inference uses the analytic influence functions with a Mammen multiplier bootstrap. Point estimates and influence-function standard errors reproduce did::att_gt to machine precision (see tests/cross/).

Usage

morie_did_group_time_att(
  data,
  outcome,
  unit,
  time,
  treatment_time,
  covariates = NULL,
  method = "doubly_robust",
  control_group = "never_treated",
  n_bootstrap = 200L,
  seed = 42L,
  alpha = 0.05,
  se_convention = "reference"
)

Arguments

data

Panel data.

outcome

Outcome column.

unit

Unit identifier.

time

Calendar-time column (integer).

treatment_time

Column with treatment-onset period (use Inf for never-treated).

covariates

Optional covariates for doubly-robust estimation.

method

One of "doubly_robust" (default), "ipw", or "outcome_regression".

control_group

"never_treated" or "not_yet_treated".

n_bootstrap

Number of multiplier-bootstrap replications for inference (0 = analytic influence-function standard errors).

seed

RNG seed for the multiplier bootstrap.

alpha

Significance level.

se_convention

For analytic (non-bootstrap) standard errors: "reference" (default) uses the did/DRDID population-sd convention so results reproduce the reference packages exactly; "bessel" keeps Bessel's correction (sd(IF)/sqrt(n)). Asymptotically equivalent.

Value

A data frame with columns cohort, time, att, std_error, ci_lower, ci_upper, p_value.

References

Callaway, B., & Sant'Anna, P. H. C. (2021). Difference-in-Differences with multiple time periods. Journal of Econometrics, 225(2), 200–230.

Examples

set.seed(4)
df <- expand.grid(unit = 1:50, time = 1:6)
df$treat_time <- ifelse(df$unit <= 25, 4, Inf)
df$d <- as.integer(df$time >= df$treat_time)
df$y <- 0.1 * df$time + 0.6 * df$d + rnorm(nrow(df), sd = 0.4)
out <- morie_did_group_time_att(df, "y", "unit", "time", "treat_time",
                                n_bootstrap = 30L, seed = 4)
head(out)
#>   cohort time         att std_error   ci_lower  ci_upper      p_value
#> 1      4    2 -0.08374062 0.1086456 -0.2966820 0.1292008 4.408440e-01
#> 2      4    3 -0.04541873 0.1488517 -0.3371626 0.2463252 7.602691e-01
#> 3      4    4  0.52334316 0.2105929  0.1105887 0.9360976 1.295172e-02
#> 4      4    5  0.57866860 0.1786949  0.2284330 0.9289042 1.202424e-03
#> 5      4    6  0.61955675 0.1064112  0.4109947 0.8281188 5.804683e-09