Section 3.14

Regression Discontinuity Design

A university awards a merit scholarship to every applicant who scores 60 or more on its entrance exam. The rule was not designed as an experiment, but it works like one. An applicant who scored 59 and an applicant who scored 61 arrived with about the same preparation and the same nerves, with two points of luck between them. Only one of them got the money. If the funded one does better in first year, the scholarship is the obvious explanation. Regression discontinuity is the method for making that comparison carefully, and for recognizing when it no longer works.

A rule, a line, and the people either side of it

The design needs three things. A running variable, which is a continuous score that every unit has: an exam mark, a household income, a birth date, a village population. A cutoff on that variable. And a rule that assigns the treatment by comparing each score with the cutoff. Benefits below an income line, a remedial class below a test score, a second teacher the moment enrollment passes forty, a pension from the month you turn sixty-five: none of these rules was made for research. Each one creates the same natural experiment.

The design works because the running variable is continuous and the treatment is not. Everything else about a person changes smoothly as their score changes. Ability, family income, motivation and whatever else drives the outcome differ a little between 59 and 61 and a lot between 40 and 80. Only the treatment jumps at the cutoff. So if the outcome jumps at exactly the cutoff, and nothing else jumps there, the treatment is the only available explanation.

The argument works only near the cutoff. It is credible because it is local, and for the same reason the estimate describes only people at the cutoff. On its own it says nothing about an applicant who scored 85 and was never at risk of missing out. A finding that a scholarship is worth five grade points at a score of 60 does not support the sentence "the scholarship is worth five grade points". The previous lesson had the same limitation: an instrument recovers the effect for the people it moved, and a cutoff recovers the effect for the people close to it.

Reading the jump off a regression

The estimate is a single regression coefficient, and the key step is centering the running variable. Replace X with X minus the cutoff, so that zero on the new scale is the threshold. Then fit

Y = b0 + b1D + b2(X − c) + b3D(X − c) + e

where D is 1 above the cutoff and 0 below it, and c is the cutoff. Each coefficient now has a clear meaning. b0 is the outcome a person right at the threshold would have had without the treatment. b2 is the slope of the outcome against the score below the cutoff, and b2 + b3 is the slope above it, so the interaction term allows the two sides to have different slopes. And b1 is the jump at the cutoff, which is the estimate. Without centering, b1 still measures a vertical gap between the two lines, but at X = 0. On an exam-score scale no applicant scores 0, and there the two fitted lines can be far apart.

Letting the slopes differ is more important than it looks. If you force a single slope across the cutoff, any bend in the underlying relationship ends up in b1, and you can report a jump that was never there. The widget below lets you try it with one click.

Keep the curve low-order. A straight line on each side inside a modest window, called local linear regression, is the modern default, and a quadratic on each side is defensible. A high-order polynomial fitted across the full range of the data is known to give unreliable estimates exactly at the boundary, where a flexible curve has the least data and the most freedom.

In the scholarship study, fitted inside twelve points either side of the cutoff, the line below predicted 62.0 at a score of 60 and the line above predicted 66.7. The scholarship is worth 4.7 grade points, SE = 1.05, t(412) = 4.48, p < .001, 95% CI [2.64, 6.76].

🎮 The Jump at the Cutoff

Six hundred applicants. The entrance exam score runs along the bottom, the first-year grade average up the side, and the scholarship goes to everyone at 60 or above (indigo). Orange lines are fitted inside the shaded window; the bracket between them at the cutoff is the estimate. The strip underneath counts applicants at each score, and that is where manipulation shows up.

True jump—
Estimated jump—
Its standard error—
Applicants in the window—
At the cutoff: below → above—

Choosing the bandwidth

Every regression discontinuity estimate is computed on a window around the cutoff, and the width of that window matters more than any other choice the analyst makes. A narrow window holds people who are more alike, so the comparison is more believable and the functional form you assumed matters less. But it also throws away most of your data, so the standard error rises. A wide window gives a more precise estimate, but the estimate then depends on the fitted line to extrapolate from scores far from the threshold.

The scholarship estimate above came from a window of twelve points, with 416 applicants in it. Refit inside five points and 154 applicants remain: the estimate moves to 5.1 and its standard error nearly doubles to 1.72, t(150) = 2.97, p = .003, 95% CI [1.70, 8.50]. Neither estimate is the right one. They come from the same design fitted with two window widths, and it is reassuring that they agree.

So the convention is to report the estimate across a range of bandwidths, usually as a small plot or a row of columns, so readers can see whether the finding depends on the choice. Published work almost always also reports a data-driven bandwidth as the main estimate. It is chosen to minimize mean squared error, and its confidence intervals are corrected for the bias that this choice leaves in. Software does that arithmetic for you.

Packages such as rdrobust also weight each observation by its distance from the cutoff. The default is a triangular kernel: full weight at the threshold, falling in a straight line to zero at the edge of the window. The fit above weights everyone in the window equally, so the package gives a different estimate on the same data even at the same bandwidth. Ask it for a uniform kernel and a bandwidth of 12, and its estimate matches the equal-weight one exactly.

Sharp cutoffs and fuzzy ones

Everything so far assumes the rule was obeyed exactly: score 60 and you are funded, score 59 and you are not. That is a sharp design, and the treatment indicator and the cutoff indicator are the same variable.

Rules are often softer. Appeals succeed, exceptions get granted, eligible people never apply. If crossing the cutoff raises the probability of treatment from 15% to 70% rather than from 0 to 1, the design is fuzzy. The jump in the outcome then understates the effect of treatment, because only 55% of the people at the cutoff changed their treatment status. Divide by that share to correct for it: the effect is the jump in the outcome divided by the jump in treatment probability.

That ratio is the Wald ratio from the previous lesson, with being above the cutoff as the instrument. Fuzzy regression discontinuity is instrumental variables: the reduced form is the jump in the outcome and the first stage is the jump in treatment. Everything from the previous lesson applies. If the cutoff barely changes who is treated, the instrument is weak. And the answer is an effect for compliers, who here are the people at the threshold whose treatment the rule actually changed.

How to referee one

Three checks separate a regression discontinuity you can believe from one you cannot. Look for all three when you read a paper that uses the design.

The outcome should jump and nothing else should. Run the same regression with a pre-treatment covariate as the dependent variable: age, prior grades, household income, anything fixed before the cutoff was applied. The treatment cannot have changed any of them. If one of them jumps significantly, the two sides of the cutoff differ for some other reason, and the design's central claim is contradicted. This is the same check as the covariate balance table in a randomized trial.

The density of the running variable should be smooth through the cutoff. This tests the assumption of no manipulation. If people can nudge their own score, those with the most to gain will push it upward, and you will see a shortage just below the line and a pile-up just above it. That pile-up ruins the comparison, because the people who moved are the ones who cared most, and they are now all on the treated side. The formal version is the McCrary density test, which estimates the density of the running variable separately on each side of the cutoff and asks whether the two estimates meet there. A significant gap is evidence of sorting. Turn the manipulation slider up in the widget: the strip under the scatter pulls apart and the estimate climbs, while the fitted lines still look tidy.

Placebo cutoffs should find nothing. Rerun the analysis pretending the threshold was at 50, or 70, or any value where no rule exists. Those regressions should return small, insignificant jumps. If the analysis finds effects at made-up cutoffs, it probably produced the effect at the real one the same way.

None of these checks tests the design's main assumption, continuity at the cutoff: everything other than the treatment varies smoothly through the cutoff. That is a statement about a counterfactual, the outcome people just above the cutoff would have had without treatment, and no dataset contains it. Each check gives the assumption a chance to fail visibly, and passing them is evidence, not proof. Section 3.12 makes the same distinction in other words: what you can adjust for depends on the data, and what you must assume depends on the design. Reading a Causal-Inference Paper applies these three checks to someone else's paper and asks whether a check that passed could ever have failed.

Why it matters: governments and institutions use thresholds everywhere, and each one can work as a natural experiment. A score, a date or a population count, plus a strict rule, is enough to get a causal estimate from records that were never collected for research. In return, you must say that the estimate is local, show it across several bandwidths, and check the density of the running variable. The next lesson covers the third of these designs, where the dividing line is a date. A policy arrives in some places and not others, and the comparison runs across places and across time at once. Quasi-experimental designs in the Research Toolkit compares all of them.

Common questions

How wide should the bandwidth be?

No width is correct in advance. The modern approach is to let an algorithm pick one and then show that the finding does not depend on it. The standard selector chooses the window that minimizes mean squared error. It balances the bias of including people far from the cutoff against the variance of excluding almost everyone, and rdrobust in R or Python reports it by default. Two practices go with it. An optimal bandwidth deliberately accepts some bias, so the ordinary confidence interval around that estimate is a little too narrow. Report the bias-corrected robust interval that the same command prints. And show a sensitivity plot: the estimate and its interval at half the selected bandwidth, at the selected one, and at twice it. An effect that appears only inside one particular window should not be reported as a finding.

My running variable only takes whole numbers. Does that break the design?

Not by itself, but it changes what you can claim and how the standard errors should be computed. The design assumes a continuous score, and an exam mark recorded in whole points is a coarse version of one. With many distinct values either side of the cutoff, the usual analysis is fine in practice. With few, two things go wrong. You cannot narrow the window to scores very close to the threshold, so the estimate depends entirely on the functional form you chose. And the conventional standard errors are too small, because everyone with the same score also shares whatever is peculiar about that score value. The standard fix is to cluster the standard errors on the running variable itself. That is the opposite of most clustering advice, but it follows from the same logic. If the score takes only a handful of values, say so, and treat the result as a parametric extrapolation, not a local comparison.

Can I add control variables to a regression discontinuity?

Yes, and the reason to add them is precision, not bias. If the design is sound, the people either side of the cutoff already match on everything. Adding a pre-treatment covariate should then leave the estimate where it was, while shrinking its standard error because the covariate explains some of the outcome's variance. That also gives you a diagnostic for free. If the estimate moves substantially when a covariate goes in, the two sides were not balanced on that covariate, and the balance check would have caught it. Two rules apply. Adjust only for variables fixed before the cutoff was applied: anything measured afterward may itself be an effect of the treatment, and adjusting for it would remove part of the effect you are estimating. And decide the covariate list before looking at what each one does to the coefficient. A list chosen by its effect on the estimate is a specification search.