Skip to content

[Lecture Idea] Difference-in-Differences with a Continuous Treatment (Callaway, Goodman-Bacon & Sant'Anna) #7

Description

@mmcky

Summary

Proposal for a new applied econometrics lecture covering modern difference-in-differences with a continuous treatment (dose), based on:

Callaway, B., Goodman-Bacon, A., & Sant'Anna, P. H. C. (2025). Difference-in-Differences with a Continuous Treatment. American Economic Review (forthcoming). [AEA page](https://www.aeaweb.org/articles?id=10.1257/aer.20240137) · [arXiv:2107.02637](https://arxiv.org/abs/2107.02637)

This is arguably the definitive treatment of continuous-dose DiD and slots naturally into a "modern econometrics" sequence alongside existing causal inference material.

Why this lecture?

  • Empirical relevance for trade/macro applications. Most real-world "treatments" in international trade are continuous: tariff changes, import-competition exposure (the ADH China shock), trade-cost reductions, exchange-rate pass-through. The workhorse approach — TWFE regression of an outcome on a continuous exposure measure — is exactly what this paper shows can be misleading.
  • Pedagogically rich. The paper cleanly separates (i) identification (ATT-type parameters under parallel trends), (ii) the selection-bias problem when comparing effects across doses (ACRT parameters need stronger assumptions), and (iii) estimation (B-splines, nonparametric sieve methods, multiplier bootstrap for uniform confidence bands). Each piece is implementable from scratch in NumPy/SciPy at lecture scale.
  • Fills a gap. QuantEcon has limited coverage of the post-2018 DiD literature (staggered adoption, negative TWFE weights, heterogeneity-robust estimators). This lecture could anchor that area.

Proposed outline

  1. Motivation — a trade example: regions exposed to a tariff cut at varying intensity. Why "run TWFE on the dose" is the default and why it's fragile.
  2. Setup and notation — potential outcomes indexed by dose Y_t(d); timing groups g; building blocks ATT(g, t, d).
  3. Identification — parallel trends identifies ATT(d); comparing across d (slopes / ACRT) requires "strong" parallel trends. Simulation demonstrating the selection-bias wedge.
  4. What TWFE actually estimates — decompose the TWFE estimand; show negative-weighting pathologies with simulated heterogeneous dose effects.
  5. Estimation — implement the ATT(d) / ACRT(d) estimators with B-splines (scipy.interpolate); event-study and dose aggregations; multiplier bootstrap for uniform confidence bands.
  6. Application — replicate (or adapt) the paper's empirical application, or a trade-flavoured alternative (e.g., regional tariff exposure).
  7. Exercises — vary the dose-effect functional form; compare TWFE vs. the robust estimator; coverage experiments for pointwise vs. uniform bands.

Implementation notes

  • Reference implementation is the authors' R package [contdid](https://bcallaway11.github.io/contdid/) (alpha, GPL-3).
  • Python ecosystem: the [diff-diff](https://diff-diff.readthedocs.io/) package (Gerber, 2026) now includes a ContinuousDiD estimator implementing CGS — B-spline dose-response curves (ATT(d) / ACRT(d)), overall ATT/ACRT aggregation, multiplier bootstrap (rademacher/mammen/webb weights) plus analytical SEs, and correct handling of the PT vs. strong-PT identification distinction. It sits within a unified scikit-learn-style API covering 13+ DiD estimators validated against R counterparts.
    • Role in the lecture: build the estimator from first principles (the pedagogical core), then close by cross-checking results against diff-diff and pointing students to it (and contdid in R) for production use. This mirrors the QuantEcon pattern of "implement it yourself, then use the library."
    • Audit task before adoption: verify diff-diff's continuous module against contdid output on fixed simulated data, and confirm coverage of staggered adoption for continuous doses (docs emphasize the dose-response core; staggered support unclear) and whether the CCK data-driven estimator is included. Findings feed the companion project issue.
  • Scope for a lecture-scale implementation: simulated panel data + B-spline dose-response estimation + multiplier bootstrap is very tractable (a few hundred lines). The data-driven sieve method (Chen, Christensen & Kankanala 2025, npiv) is harder and could be mentioned rather than implemented, or deferred to a follow-up.
  • License note: contdid is GPL-3. The lecture should reimplement from the paper's equations rather than translating package source, to keep our standard BSD-3/CC licensing clean. (Check diff-diff's license before recommending it in lecture text — likely permissive, but confirm.)
  • Possible synergy: the estimators here build on the did / ptetools ecosystem; if we later cover Callaway & Sant'Anna (2021) staggered DiD, diff-diff also covers that estimator, so the two lectures could share both from-scratch infrastructure and the same production-library endpoint.

Open questions

  • Which repo/series does this belong in?
  • Simulated data only, or include an empirical replication (data availability/licensing to check)?
  • Implement CCK nonparametric estimator, or B-spline parametric only?
  • JAX or NumPy for the bootstrap? (multiplier bootstrap vectorises nicely in either)
  • Use diff-diff as the lecture's validation cross-check and "production use" recommendation, pending the audit above?

References

  • Callaway, Goodman-Bacon & Sant'Anna (2025), DiD with a Continuous Treatment, AER forthcoming.
  • Chen, Christensen & Kankanala (2025), "Adaptive Estimation and Uniform Confidence Bands for Nonparametric Structural Functions and Elasticities", REStud 92(1).
  • Callaway & Sant'Anna (2021), "Difference-in-Differences with Multiple Time Periods", J. Econometrics.
  • Goodman-Bacon (2021), "Difference-in-Differences with Variation in Treatment Timing", J. Econometrics.
  • contdid (R, reference implementation): https://bcallaway11.github.io/contdid/
  • diff-diff (Python): https://diff-diff.readthedocs.io/ContinuousDiD module: https://diff-diff.readthedocs.io/en/stable/api/continuous_did.html

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions