Kyle Butts1
1University of Colorado: Boulder
Empirical work often uses treatment assigned following geographic boundaries. When the effects of treatment cross over borders, classical difference-in-differences estimation produces biased estimates for the average treatment effect. In this paper, I introduce a potential outcomes framework to model spillover effects and decompose the estimate's bias in two parts: (1) the control group no longer identifies the counterfactual trend because their outcomes are affected by treatment and (2) changes in treated units' outcomes reflect the effect of their own treatment status and the effect from the treatment status of ``close'' units. I propose estimation strategies that can remove both sources of bias and semi-parametrically estimate the spillover effects themselves including in settings with staggered treatment timing. To highlight the importance of spillover effects, I revisit analyses of three place-based interventions.
Figure 1: Comparison of Single vs. Multiple Rings Estimation of Spillover Effects
code/rings-example/rings_example.R
Figure 2: TVA Effective Sample and Spillover Variables
code/tva/tva-data-build.docode/tva/analysis.R
Table 1: Effects of Tennessee Valley Authority on Decadel Growth
code/tva/tva-data-build.docode/tva/analysis.R
Table B1: Effects of Opportunity Zones on Annual Home Price Growth
code/OZ/replication.Rcode/OZ/spillovers.R
Figure C1: Total and Spillover Effects of Community Health Centers
code/CHC/analysis.R
.
├── code/
│ ├── main.R # Main script to run all analyses
│ ├── rings-example/ # Figure 1: Single vs. Multiple Rings
│ │ └── rings_example.R # Generates comparison figures
│ ├── TVA/ # Table 1: Tennessee Valley Authority
│ │ ├── analysis.R # Main analysis and Figure 2
│ │ ├── analysis_1930_base.R # Alternative baseline (1930)
│ │ ├── tva-data-build.do # Stata data preparation
│ │ ├── helpers.R # Helper functions
│ │ ├── helper-conley.R # Conley standard errors
│ │ ├── helper-conley.cpp # C++ implementation
│ │ └── pretrends.R # Pretrend analysis
│ ├── CHC/ # Figure C1: Community Health Centers
│ │ └── analysis.R # Event study analysis
│ ├── OZ/ # Table B1: Opportunity Zones
│ │ ├── replication.R # Replicate CGW (2023)
│ │ └── spillovers.R # Add spillover controls
│ └── simulations/ # Monte Carlo simulations
│ ├── misspecified_exposure_mapping.R
│ ├── helper-sim_function.R
│ ├── helper-sim_function_misspecification.R
│ └── prepare_county_data.R
├── out/
│ ├── figures/ # Generated figures
│ │ ├── rings-example/ # Figure 1 outputs
│ │ ├── tva/ # Figure 2 outputs
│ │ ├── chc/ # Figure C1 outputs
│ │ └── example/ # Additional examples
│ └── tables/ # Generated tables
│ ├── tva_long.tex # Table 1 (long differences)
│ ├── tva_short.tex # Table 1 (short differences)
│ ├── tva_long_1930.tex # Alternative baseline
│ ├── tva_replication.tex # Replication table
│ ├── tva_replication_short.tex # Short replication
│ └── OZ_replication.tex # Table B1
└── data/ # Data files (not tracked in git)
| Script | Purpose | Outputs |
|---|---|---|
code/rings-example/rings_example.R |
Figure 1: Single vs. Multiple Rings estimation comparison | rings_pt_everywhere.pdf, rings_pt_on_avg.pdf, rings_v_within_pt_everywhere.pdf, rings_v_within_pt_on_avg.pdf, within_pt_everywhere.pdf, within_pt_on_avg.pdf |
code/TVA/analysis.R |
Figure 2 & Table 1: TVA analysis with spillover controls | tva-sample.pdf, tva_long.tex, tva_short.tex |
code/TVA/analysis_1930_base.R |
Alternative TVA analysis with 1930 baseline | tva_long_1930.tex, tva_short_1930.tex |
code/CHC/analysis.R |
Figure C1: CHC event study with spillovers | chc-es_original.pdf, chc-es_combined.pdf |
code/OZ/replication.R |
Table B1: Replicate CGW (2023) | OZ_replication.tex |
code/OZ/spillovers.R |
Add spillover controls to OZ analysis | Same as above |
code/simulations/misspecified_exposure_mapping.R |
Misspecification simulations | misspecification.tex, misspecification_mspe.tex, misspecification_mspe_percent.tex |
Execute all analyses:
source("code/main.R")Or use the render system for individual files:
source("logbook/render_file.R")
render_file(here("code/TVA/analysis.R"))@article{butts2023difference,
title={Difference-in-Differences Estimation with Spatial Spillovers},
author={Butts, Kyle},
journal={arXiv preprint arXiv:2105.03737},
year={2023}
}