tidyMacro tidyMacro tidyMacro
  • PDF
  1. 12  Local Projections Difference-in-Differences
  • 1  Home
  • 2  Short run restrictions
  • 3  Long run restrictions
  • 4  Mixed restrictions
  • 5  Proxy SVAR (External Instruments) and Weak-IV Robust Inference
  • 6  Internal Instruments: Cholesky on Augmented VAR
  • 7  Identification via Heteroskedasticity
  • 8  External instrument SVAR analysis for noninvertible shocks
  • 9  Local Projections — Common Syntax and Conventions
  • 10  Local Projections with Shocks and IV
  • 11  Panel Local Projections
  • 12  Local Projections Difference-in-Differences

12  Local Projections Difference-in-Differences

Replicating Dube, Girardi, Jordà and Taylor 2025

12.1 Overview

This chapter replicates the two empirical applications of Dube et al. (2025) with fLPDID() and fPlotLPDID(). Shared conventions across the LP engines — formula grammar, ..macros, gap-safe l() / f() / d(), panel_id handling, duplicate-row rejection, output tibble shape — are documented once in the Local Projections syntax primer. Below we focus on what is DiD-specific.

For each horizon \(h\) the long-difference regression \[y_{i,t+h} - y_{i,t-1} \;=\; \beta_h \,\Delta D_{it} \;+\; X_{it}'\gamma_h \;+\; \tau_t \;+\; \varepsilon_{it}\] is fit on a clean-control sample (newly treated units and units that stay untreated over the relevant window). Pre-treatment horizons replace \(y_{i,t+h}\) by \(y_{i,t-j}\) as placebo tests, with \(\beta_{-1}=0\) as the normalization.

Estimator-specific arguments (beyond the shared list; see ?fLPDID for the full API):

  • post, pre — event-time windows (fLPDID() uses these instead of horizons).
  • treat — name of the treatment level column.
  • cluster — cluster column for the CR1 sandwich (default = unit id).
  • nonabsorbing = TRUE — non-absorbing treatment; requires the stabilization window L and the clean-control flavor ccc ∈ {0, 1, 2}.
  • pmd = TRUE — pre-mean-differenced baseline (Stata calendar-time formula, see §5 of the syntax primer).
  • reweight = TRUE — equally-weighted ATT via \(w = 1/(1-p_t)\); with non-empty controls this is not the DDCG teffects ra estimator and the function warns accordingly.
  • Time fixed effects are always absorbed (they are part of the estimator); unit effects are removed by the long difference. Any | time you write is accepted but redundant.
library(tidyMacro)
library(tidyverse)
set_theme(fThemeTidyMacro())

data("BankingDeregulation")
data("DemocracyGrowth")

12.2 Banking deregulation and the labor share

The first application (DGJT, Figure 3) revisits the effect of US inter-state banking deregulation on the private labor share: 46 states, 1970–1996, absorbing staggered treatment.

bank_fe <- fLPDID(
    lshare ~ bank,
    data     = BankingDeregulation, 
    panel_id = c("id", "year"),
    treat    = "bank", 
    post     = 9, pre = 9
)

bank_ylags <- fLPDID(
    lshare ~ bank + l(lshare, 1:4) + l(d(lshare), 1:4),
    data = BankingDeregulation, 
    panel_id = c("id", "year"),
    treat = "bank", post = 9, pre = 9
)

# additional controls via a ..macro, as in fixest
ctrl <- c("grgsp", "corptax", "unionmem")

bank_full <- fLPDID(
    lshare ~ bank + l(lshare, 1:4) + l(d(lshare), 1:4) + l(..ctrl, 1:4),
    data = BankingDeregulation, 
    panel_id = c("id", "year"),
    treat = "bank", post = 9, pre = 9
)
fPlotLPDID(`Only year FEs`               = bank_fe,
           `+ lagged labor share`        = bank_ylags,
           `+ lagged share and controls` = bank_full,
           ncol  = 3, ci = "bars", scales = "fixed",
           title = "Banking deregulation and the labor share (LP-DiD)",
           xlab  = "Years since deregulation",
           ylab  = "Labor share")

Across specifications the LP-DiD estimates are small and statistically indistinguishable from zero — DGJT’s point: the large negative effects found by two-way fixed-effects event studies in this setting are an artifact of forbidden comparisons, not a feature of the data. The same exercise for intra-state branching amounts to fLPDID(lshare ~ branch, ..., treat = "branch").

12.3 Variance-weighted vs. equally-weighted ATT

By default the LP-DiD OLS coefficient is a variance-weighted average of clean \(2\times2\) comparisons — efficient, but it overweights treatment cohorts observed when the treated share is small. Setting reweight = TRUE inverts the implicit weights (\(w = 1/(1-p_t)\)) and recovers the equally-weighted ATT.

bank_rw <- fLPDID(lshare ~ bank,
                  data = BankingDeregulation, panel_id = c("id", "year"),
                  treat = "bank", post = 9, pre = 9,
                  reweight = TRUE)
fPlotLPDID(`Variance-weighted (OLS)` = bank_fe,
           `Equally-weighted ATT`    = bank_rw,
           ncol  = 3, ci = "bars", scales = "fixed",
           title = "Weighting and the estimand",
           xlab  = "Years since deregulation",
           ylab  = "Labor share")

12.4 Democracy and growth (non-absorbing treatment)

The second application (DGJT, Figure 4) revisits Acemoglu et al. (2019) . Treatment is non-absorbing — countries democratize and revert — and its timing is endogenous to past GDP dynamics, so all specifications control for four lags of GDP (l(lgdp, 1:4)) and clean-control samples are built recursively over a stabilization window of \(L = 20\) years.

Three flavors of the clean-control condition (ccc):

  • ccc = 0 — no restriction beyond the transition definition (the original ANRR local-projection specification);
  • ccc = 1 — treated and controls must have a clean past (no democracy transitions within the last \(L\) years);
  • ccc = 2 — controls must additionally remain clean up to \(t+h\).
demo_anrr <- fLPDID(lgdp ~ dem + l(lgdp, 1:4),
                    data = DemocracyGrowth, panel_id = c("id", "year"),
                    treat = "dem", post = 30, pre = 20,
                    nonabsorbing = TRUE, L = 20, ccc = 0)

demo_ccc1 <- fLPDID(lgdp ~ dem + l(lgdp, 1:4),
                    data = DemocracyGrowth, panel_id = c("id", "year"),
                    treat = "dem", post = 30, pre = 20,
                    nonabsorbing = TRUE, L = 20, ccc = 1)

demo_ccc2 <- fLPDID(lgdp ~ dem + l(lgdp, 1:4),
                    data = DemocracyGrowth, panel_id = c("id", "year"),
                    treat = "dem", post = 30, pre = 20,
                    nonabsorbing = TRUE, L = 20, ccc = 2)
fPlotLPDID(
  `ANRR LP specification` = demo_anrr,
  `LP-DiD (CCC 1)`        = demo_ccc1,
  `LP-DiD (CCC 2)`        = demo_ccc2,
  ncol  = 3, scales = 'free',
  title = "Democracy and growth (LP-DiD)",
  xlab  = "Years since democratization",
  ylab  = "GDP per capita (log x 100)"
) +
  ylim(-40, 60)

Democratization raises GDP per capita by roughly 15–25 log points over 25–30 years, with flat pre-trends. Restricting to clean controls (ccc = 1, 2) moderates the ANRR estimates, as contaminated comparisons are removed from the control group.

12.5 Notes on the implementation

Generic behavior — gap-safe operators, duplicate (id, time) rejection, argument validation, PMD baseline formula, reweight + controls warning, direct-C++ boundary checks — is documented in the syntax primer. The two items below are LP-DiD-specific and worth flagging in the empirical context:

  • Weighting. reweight = TRUE implements the inverse implicit weights of the exogenous/absorbing case. The regression-adjustment (ATET) reweighting DGJT use in the non-absorbing case is not in the C++ engine; the runtime warning triggered by reweight = TRUE with non-empty controls makes this explicit at the point of use.
  • Missing-value semantics for clean-control sets. The recursive CCS follow Stata’s conventions at panel boundaries: a missing treatment change counts as “no change” (condition OK); a missing lagged clean-control flag counts as failing the condition. This matters for reproducing the original results observation-for-observation.

References

Acemoglu, Daron, Suresh Naidu, Pascual Restrepo, and James A. Robinson. 2019. “Democracy Does Cause Growth.” Journal of Political Economy 127 (1): 47–100. https://doi.org/10.1086/700936.
Dube, Arindrajit, Daniele Girardi, Òscar Jordà, and Alan M. Taylor. 2025. “A Local Projections Approach to Difference-in-Differences.” Journal of Applied Econometrics 40 (7): 741–58. https://doi.org/10.1002/jae.70000.
11  Panel Local Projections

Built with Quarto

© 2025 Muhsin Ciftci · Goethe University Frankfurt

  • Edit this page
  • Report an issue

tidyMacro