ECON 4309 · Quantitative Methods for Social Sciences · Reading companion
Regression Discontinuity, in about 15 minutes
A plain-language guide to Chapter 20 of The Effect by Nick Huntington-Klein. Read this first, play with the two simulators, and then use the reading guide at the end to decide which parts of the chapter to read closely.
Note: This is the printable version. The interactive version, with the simulators, is on the course website.
1. The big idea in 60 seconds
The chapter opens in San Diego. If you drive 16 miles south from downtown to the border, household income falls gradually, from about $85,000 to about $50,000. Then you take one step across the border into Tijuana and income drops to about $20,000. Neighborhoods a few feet apart can't be that different "naturally," so the jump has to come from the line itself.
Regression discontinuity (RDD) uses the same logic. Many programs are handed out by a rule with a cutoff: score 70 or lower and you get a tutor; earn below $X and you get a check. People just barely on either side of that cutoff are almost identical. If their outcomes jump at the cutoff, the program caused the jump.
In the chapter's words, the recipe has three parts:
- Account for how the running variable normally relates to the outcome (draw a line on each side).
- Focus on the observations close to the cutoff.
- Compare the just-barely-treated with the just-barely-untreated. The size of the gap is your estimate.
2. Six words you need
We'll use the tutoring example from Lecture 10 throughout: students take an entrance exam, those who score 70 or lower get a free tutor, and at the end of the year everyone takes an exit exam.
3. Simulator: draw the lines, measure the gap
The data below are simulated, so we know the truth: tutoring raises the exit-exam score by exactly 10 points. Your job is to estimate that 10 from the data. The estimate is the gap between the two fitted lines at the cutoff.
Tutoring program: entrance exam vs. exit exam
Students scoring ≤ 70 get a tutor (orange). Faded points are outside your bandwidth and aren't used.
- Try 1: Straight lines, bandwidth ±45 (all the data), then "Repeat 200 times." The dots bunch tightly, but around the wrong number. That's bias: far from 70, the straight line doesn't match the curve.
- Try 2: Bandwidth ±3. Now the dots center on 10 but spread out a lot. That's noise: there are only a few students near 70.
- Try 3: Find a middle setting (around ±8 to ±12) where the dots are both centered and fairly tight. Then switch to curved lines at a wide bandwidth and compare.
4. Why this counts as causal
Here is the chapter's causal diagram (Figure 20.1), simplified. Z stands for everything we can't measure, such as motivation, family background, and test anxiety.
Tutoring has a back door, because tutoring ← cutoff ← entrance score → exit score, and Z affects the entrance score too. RDD handles this by looking only right at the cutoff. There, a student at 69.5 and a student at 70.5 have essentially the same Z and the same "normal" relationship with the exit score. The only thing that changes is tutoring. So the jump isolates the tutoring → exit score arrow, even though we never measured Z.
5. What has to be true (and how to check it)
Assumption 1: Nothing else jumps at the cutoff
RDD really measures the effect of crossing the line and credits all of it to the treatment. If a score of 70 also got you into a summer camp, you couldn't separate tutoring from camp. The chapter's example: if a score of 95 gets you into both the gifted program and a museum field trip, RDD can't tell the two apart. You can't test this assumption directly. You have to know your setting.
How to check it: placebo tests. Run the same RDD on things tutoring can't affect, such as age, gender, or parents' education. They should not jump at 70. If they do, the two sides aren't comparable. (If you test 20 variables, one or two may "jump" by chance. That's normal.)
Assumption 2: Nobody manipulates the running variable
The design depends on people landing just above or just below the cutoff by luck. It breaks if:
- People control their own score. The chapter's example: a store discounts tuna if you buy 12+ cans, and you choose how many cans to buy. Here, students who want a free tutor could deliberately underperform to score just below 70.
- Someone else nudges the score. A teacher regrades a 94 to a 96 to get a student into the gifted program, or a friendly timer shaves two seconds off your mile.
- The cutoff is set after looking at who it affects. A coach sets the team cutoff at 5:37 right after his son runs 5:35.
How to check it: the density (McCrary) test. Plot a histogram of the running variable. Without manipulation it should be smooth across the cutoff. A pile-up on one side and a hole on the other is a red flag.
Simulator: can you spot manipulation?
The histogram shows how many students got each entrance-exam score. Slide up the share of students who know the cutoff and aim for "just under 70" to get the free tutor.
Assumption 3 (practical): enough precise data near the cutoff
RDD throws most of the data away, so you need a lot of observations near the cutoff (the lecture calls RDD "greedy"). The running variable also has to be measured precisely. If scores were only reported in bins like "60–69" and "70–79," you couldn't compare a 69 with a 71.
6. Sharp vs. fuzzy RDD
In a sharp RDD everyone below the cutoff is treated and nobody above it is. Real life is often fuzzy: crossing the cutoff only makes treatment more likely. The chapter's example (Battistin et al., 2009) is retirement in Italy. When men become eligible for a pension, the share who are retired jumps by about 30 percentage points, not 100.
If you ran a regular RDD on consumption, you'd see a small jump, because only 30% of people actually switched. The fix is to scale up: divide the jump in the outcome by the jump in the treatment rate. This is instrumental variables (IV), and you'll see it again in the IV lectures, with "being past the cutoff" as the instrument.
Mini-calculator
When the jump in treatment is 100 points (everyone switches), the fuzzy estimate equals the sharp estimate. The smaller the jump in treatment, the more you have to scale up, and the noisier the estimate gets.
7. What you actually estimate: a LATE
Because RDD only uses people near the cutoff, it tells you the effect for people near the cutoff, a local average treatment effect.
8. Doing it in R (with AI help)
In this class, AI writes most of the code. Your job is the design and the checking. These are the steps an RDD analysis should include and what to verify at each one:
| Step | Typical R | What you check |
|---|---|---|
| 1. Center the running variable | mutate(entrance_centered = entrance_exam - 70) | Is the cutoff right, and is treatment on the correct side (≤ 70 here)? |
| 2. Plot it first | rdplot(y, x, c = 70) or a binned scatter with ggplot | Can you see a jump with your own eyes? |
| 3. Simple regression | lm(exit_exam ~ entrance_centered + tutoring, data = filter(df, abs(entrance_centered) <= 10)) | The tutoring coefficient is the gap. Is its sign sensible? |
| 4. Robust estimate | rdrobust(y, x, c = 70) | What bandwidth did it choose? Does the estimate hold up at double and half that bandwidth? |
| 5. Manipulation test | rddensity(x, c = 70), rdplotdensity() | Is there a pile-up or a hole at 70? |
| 6. Placebo tests | Repeat step 4 with a pre-treatment variable as y | No jump in things tutoring can't affect. |
| (Fuzzy only) | rdrobust(y, x, c = 70, fuzzy = treated) | Is there a clear jump in the share treated? |
rdrobustIt assumes treatment is on the right of the cutoff. When treatment is below the cutoff, as with tutoring, the sign of the estimate is flipped: a "−10" means tutoring raised scores by 10. The chapter also shows that rdrobust and a hand-built regression can give quite different answers when they use different bandwidths. A package doesn't make the decisions for you.- Forgetting to center the running variable. The treatment coefficient is then no longer the gap at the cutoff.
- Using a 5th-order polynomial to "fit better."
- Reporting only one bandwidth.
- Claiming the effect applies to everyone (it's a LATE).
- Skipping the density test and the placebo tests.
- Clustering standard errors on the running variable. The chapter says this used to be common, but don't do it.
9. How to read the chapter
The chapter is long (about 20,000 words) and written partly for graduate students. Here's where to spend your time:
| Section | What it covers | |
|---|---|---|
| 20.1 How Does It Work? | The intuition, the vocabulary, the causal diagram, the assumptions, and the LATE. Everything on this page except the R. | Read closely |
| 20.2.1 RDD with OLS | The regression equation, why to avoid high-order polynomials, local regression, kernels, and code. Read the text; you can skim the code. | Skim |
| 20.2.2 Fuzzy RDD | Scaling with IV, and the GI Bill/home-ownership example. The first half is the important part. | Skim |
| 20.2.3 Placebo Tests | Short and directly useful for your assignment. | Read |
| 20.2.4 Density Test | Manipulation stories (tuna cans, track tryouts) and the density test. | Read |
| 20.3.4 Dealing with Bandwidths | Three ways to choose a bandwidth (just pick one; try many; let the data choose). | Skim |
| 20.3.1–20.3.3 | Regression kink, multiple cutoffs, and heaping. Beyond this course. | Optional |