Regression discontinuity
When a rule draws a sharp line — scholarships at 75 marks, overdraft fees at zero balance — the people huddled on either side are nearly identical, and the jump between them is the causal effect.
- 7 min read
- 3 reading levels
- Published
Read these first
On this page 5
One lesson, three depths. Pick the one that fits you today — you can switch any time.
Beginner — No maths. Plain English.
Regression discontinuity (RD) measures a rule's effect by comparing people who fell a hair's breadth on either side of its cutoff line.
A scholarship goes to every student scoring 75 or above. A student with 74.9 and one with 75.1 are, for all practical purposes, the same student. Same preparation, same ability, same luck of one exam question. Yet the rule hands one of them a scholarship and not the other. Right at the line, the rule behaves like a coin toss — and a coin toss is an experiment.
So: compare outcomes of the students hugging the cutoff from both sides. Any jump exactly at the line belongs to the scholarship, because nothing else changes abruptly at 75.
Why it exists
Comparing all scholarship winners against all non-winners is hopeless — winners scored higher, and high scorers differ in a hundred ways that also shape their futures. Classic confounding.
But the rule itself manufactures a tiny natural experiment at its boundary. No one controls their mark to a tenth of a point, so falling at 74.9 versus 75.1 is luck. Bureaucratic sharpness — usually a nuisance — becomes an identification machine.
How it works
future
success │ ● ● ●
│ ● ● ●
│ ↑ jump = the effect
│ ○ ○ ○
│ ○ ○ ○
└───────────────┼──────────────── exam marks
75
○ no scholarship ● scholarshipFit a line through the left-side points, another through the right-side points, and read both lines' heights at the cutoff. The gap between the two heights is the effect. Points far from the line contribute shape, but the verdict is delivered at the boundary.
One honest limit: the answer describes borderline students. Whether the scholarship transforms a 95-mark topper, RD cannot say — no coin was tossed for them.
A real example you have seen
Cutoff rules run the world. College admission marks. BPL income lines — Below Poverty Line — for welfare schemes. A minimum order value for free delivery. Credit score lines for loan approval. Age cutoffs for school entry. Each sharp line is a ready-made study. Economists mined the school-entry age cutoff to measure how an extra year of maturity changes exam outcomes — comparing children born days apart across the line.
Remember this
- People on either side of a cutoff are nearly identical — the rule tosses their coin.
- The effect is the jump in outcomes exactly at the line.
- The answer is local: it speaks about borderline cases, not everyone.
What to learn next
- Instrumental variables — the general machinery behind fuzzy cutoffs.
- Difference-in-differences — identification from time when no cutoff exists.
- Linear regression — the line-fitting engine RD runs twice.
Developer — Code and libraries.
Setup
pip install numpyVerified with numpy 1.26.4.
Naive comparison versus the jump at the line
Marks help future results on their own (0.05 GPA per mark), and the scholarship at 75 adds a true +0.6. The naive comparison bundles both; RD isolates the second.
import numpy as np
rng = np.random.default_rng(16)
n = 4000
marks = rng.uniform(40, 100, n)
scholarship = marks >= 75 # the rule: 75 marks or above
gpa = 4 + 0.05 * marks + 0.6 * scholarship + rng.normal(0, 0.3, n)
naive = gpa[scholarship].mean() - gpa[~scholarship].mean()
print(f"all students compared: {naive:+.3f}")
def line_at_cutoff(side):
m = side & (np.abs(marks - 75) < 10) # a 10-mark window each side
slope, intercept = np.polyfit(marks[m] - 75, gpa[m], 1)
return intercept # the line's value AT the cutoff
jump = line_at_cutoff(scholarship) - line_at_cutoff(~scholarship)
print(f"jump at the cutoff: {jump:+.3f} (truth: +0.600)")all students compared: +2.098 jump at the cutoff: +0.607 (truth: +0.600)
The walkthrough
The naive gap is +2.098 — three and a half times the truth. Winners average 15 marks higher than non-winners, and those marks carry their own +0.05 each. Ability rides along with the scholarship in any global comparison.
marks - 75 centres the running variable. After centring, a fitted line's intercept is its value exactly at the cutoff — which is the only place the comparison is fair. np.polyfit (from the linear regression family) fits each side separately, letting slopes differ.
The 10-mark window is the bandwidth — the tuning knob of every RD. Wide windows use more data (smaller error bars) but lean harder on the straight-line approximation far from the cutoff (more bias). Serious analyses report several bandwidths; a result that survives halving the window earns trust.
Separate lines per side matter. Forcing one shared slope lets data from 40 marks influence the estimated jump at 75 — exactly the contamination the design exists to avoid.
Common mistakes
Using people far from the line as if they were near it. With a very wide window and curvy reality, the straight lines mis-extrapolate to the boundary and the "jump" absorbs curvature. When in doubt, shrink the window and watch the estimate.
Skipping the manipulation check. If people can choose their side — teachers nudging 74.9 to 75.0 out of kindness — the coin toss dies, and the huddle at 75.0 is self-selected. Diagnostic: histogram the running variable; a suspicious spike at the cutoff (checked formally by the McCrary density test) voids the design.
Ignoring other rules sharing the cutoff. If 75 also triggers a certificate, a better hostel and a different class section, the jump bundles all of them. The design identifies the bundle at the line; separating requires cutoffs that differ.
Selling the local effect as the global one. +0.6 for borderline students is the finding. Extending it to top scorers is extrapolation the data never authorised — state the population honestly.
Try it yourself
Add curvature — 0.001 * (marks - 40) ** 2 — and rerun at bandwidths 20, 10, 5 and 2. Watch bias shrink and noise grow as the window narrows: the RD bandwidth trade-off in your own output. Then simulate manipulation by shifting a third of the 73–75 students to exactly 75, and check the histogram spike plus what happens to the estimate.
What to learn next
- Instrumental variables — the general machinery behind fuzzy cutoffs.
- Difference-in-differences — identification from time when no cutoff exists.
- Linear regression — the line-fitting engine RD runs twice.
Researcher — Mathematics and papers.
Identification
Let $X$ be the running variable with cutoff $c$, treatment $T = \mathbb{1}[X \ge c]$ (sharp RD). The estimand is the local effect at the cutoff:
$$ \tau_{RD} = \mathbb{E}[Y(1) - Y(0) \mid X = c] = \lim_{x \downarrow c} \mathbb{E}[Y \mid X = x] - \lim_{x \uparrow c} \mathbb{E}[Y \mid X = x] $$
- $X$ — the assignment (running) variable; $c$ — the cutoff.
- The identifying assumption: $\mathbb{E}[Y(0) \mid X = x]$ and $\mathbb{E}[Y(1) \mid X = x]$ are continuous in $x$ at $c$ (Hahn, Todd and van der Klaauw, 2001, Econometrica). Everything else may correlate with $X$ arbitrarily.
Continuity fails under precise manipulation of $X$; McCrary (2008, J. Econometrics) tests for a density discontinuity at $c$. Covariate balance at the cutoff (pre-determined characteristics showing no jump) is the standard falsification suite, alongside placebo cutoffs.
Estimation
Local linear regression on each side with kernel weights is the standard (local constant is boundary-biased; higher-order polynomials are discouraged — Gelman and Imbens, 2019, JBES, show global polynomials produce noise-driven jumps). Bandwidth selection: Imbens and Kalyanaraman (2012, ReStud) MSE-optimal rule, refined by Calonico, Cattaneo and Titiunik (2014, Econometrica), whose robust bias-corrected inference (the rdrobust package) is the current default: MSE-optimal bandwidth, bias correction for the resulting first-order bias, and adjusted standard errors.
Fuzzy RD
When the cutoff shifts treatment probability discontinuously without determinism (eligibility, not receipt):
$$ \tau_{FRD} = \frac{\lim_{x \downarrow c} \mathbb{E}[Y \mid X{=}x] - \lim_{x \uparrow c} \mathbb{E}[Y \mid X{=}x]} {\lim_{x \downarrow c} \mathbb{E}[T \mid X{=}x] - \lim_{x \uparrow c} \mathbb{E}[T \mid X{=}x]} $$
— the outcome jump scaled by the take-up jump. This is instrumental-variables logic with the cutoff as instrument, estimating a local LATE for cutoff-compliers; the machinery arrives in instrumental variables.
Scope and lineage
- Thistlethwaite and Campbell (1960) — the original scholarship study, ignored for forty years.
- Lee (2008, J. Econometrics) — incumbency effects via vote-share cutoffs; Lee and Lemieux (2010, JEL) — the survey that standardised practice.
- Regression kink designs (Card, Lee, Pei and Weber, 2015, Econometrica) — identification from slope changes rather than jumps.
- ML connections: cutoff-based decisioning (credit scores, risk tiers) makes RD the natural audit tool for deployed model thresholds — the jump at a score cutoff measures the policy's causal effect at the margin, informing threshold-moving decisions directly.
What to learn next
- Instrumental variables — the general machinery behind fuzzy cutoffs.
- Difference-in-differences — identification from time when no cutoff exists.
- Linear regression — the line-fitting engine RD runs twice.