RDD — Regression Discontinuity Design
RDD evaluates causal impact when treatment is determined by a cutoff in a running variable — e.g. a test score ≥ threshold qualifies for a scholarship. Comparing units just above and just below the cutoff (as-good-as random) yields a credible causal estimate at the threshold.
Sharp vs Fuzzy
Sharp RDD: crossing the cutoff ⇒ surely treated. Fuzzy RDD: crossing only increases the probability of treatment ⇒ combine with IV (using the cutoff as instrument).
Intuition
Estimate the jump in at the threshold ; this is the local causal effect (LATE) at the cutoff.
Running in EcoLab
- Modeling module → Causal inference family → RDD.
- Declare the running variable, cutoff, and outcome; choose sharp/fuzzy, bandwidth, polynomial order.
- Run; view the RDD plot + estimate at the cutoff; run the McCrary test (manipulation); export the replication code.
Replication code
- Stata
- R
- Python
* ── RDD estimation ────────────────────────────────
* Install: ssc install rdrobust
rdrobust y score, c(50)
* ── RDD plot ──────────────────────────────────────
rdplot y score, c(50)
* ── Bandwidth selection ───────────────────────────
rdbwselect y score, c(50)
# ── RDD estimation ────────────────────────────────
library(rdrobust)
# Robust RD estimate at cutoff = 50
rd <- rdrobust(df$y, df$score, c = 50)
summary(rd)
# RDD plot
rdplot(df$y, df$score, c = 50,
title = "RDD plot",
x.label = "Running variable (score)",
y.label = "Outcome (Y)")
# ── RDD estimation ────────────────────────────────
from rdrobust import rdrobust, rdplot
# Robust RD estimate at cutoff = 50
rd = rdrobust(df["y"], df["score"], c=50)
print(rd)
# RDD plot
rdplot(df["y"], df["score"], c=50,
title="RDD plot",
x_label="Running variable (score)",
y_label="Outcome (Y)")
Limitations
- Identifies only a local effect at the cutoff (LATE), not generalizable to the whole sample.
- Sensitive to bandwidth and functional form; check for manipulation of the running variable.