{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3"
  },
  "language_info": {
   "name": "python"
  },
  "colab": {
   "provenance": []
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Day 78: Regression Kink & RD Extensions\n",
    "\n",
    "*Beginner to Ninja: Math for Causal Inference*\n",
    "\n",
    "Some policies change the slope of a schedule rather than its level, such as a benefit capped at a maximum. The regression kink design divides the change in the outcome's slope by the change in the policy's slope. Also: geographic boundaries, multiple cutoffs and RD in time.\n",
    "\n",
    "**Learning outcomes**\n",
    "\n",
    "- Define the regression kink estimand and the smoothness assumptions it requires.\n",
    "- Estimate slope changes with local polynomials and explain why they are noisier than jumps.\n",
    "- Extend RD to multiple cutoffs, geographic boundaries and time, and list each extension's threats.\n",
    "- Apply RKD to unemployment benefits and other capped or tiered schedules."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Theory\n",
    "\n",
    "### Kinked policies\n",
    "\n",
    "A policy variable $B = b(X)$ is a **continuous** function of the running variable with a **kink** at $c$: its slope changes from $b'(c^-)$ to $b'(c^+)$. Examples: unemployment benefits equal to 50% of past earnings up to a maximum; tax credits that phase in and out; co-payment schedules.\n",
    "\n",
    "### The RKD estimand\n",
    "\n",
    "If $Y = g(B, X, \\varepsilon)$, then\n",
    "\n",
    "$$\n",
    "\\tau_{RKD} = \\frac{\\lim_{x \\downarrow c}\\frac{d}{dx}E[Y \\mid X = x] - \\lim_{x \\uparrow c}\\frac{d}{dx}E[Y \\mid X = x]}{b'(c^+) - b'(c^-)}\n",
    "$$\n",
    "\n",
    "identifies the (average) marginal effect of $B$ on $Y$ at $c$, under **smoothness**: the density of $X$ and the direct dependence of $Y$ on $X$ have continuous derivatives at $c$ (Card, Lee, Pei and Weber, 2015). With imperfect implementation (actual benefits deviate from the formula), a **fuzzy RKD** divides by the estimated kink in actual $B$.\n",
    "\n",
    "### Estimation\n",
    "\n",
    "Fit local polynomials on each side and compare the **slopes** at $c$ (local linear or local quadratic, with a kink term $(X - c)\\mathbf 1[X \\ge c]$). Derivatives are harder to estimate than levels: the variance of a slope estimate scales like $1/(nh^3)$ instead of $1/(nh)$, so RKD needs large samples (administrative data).\n",
    "\n",
    "### Extensions of RD\n",
    "\n",
    "- **Multiple cutoffs:** different cohorts or regions have different thresholds; normalise $X - c_j$ and pool (a weighted average of cutoff-specific effects), or exploit the variation to learn how effects change with the cutoff.\n",
    "- **Geographic RD:** a boundary separates treated from untreated areas (school districts, states with different laws). The running variable is distance to the boundary (two-dimensional). Threats: other policies change at the same border; people sort across borders.\n",
    "- **RD in time:** treatment starts on a date. Concerns: other things change at the same time, anticipation and adjustment, serial correlation; often closer to an interrupted time series than an RD.\n",
    "- **Extrapolation:** with assumptions (for example, conditional independence of $X$ and outcomes given covariates), effects away from the cutoff can be estimated.\n",
    "\n",
    "## Part 1 · Warm-up"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 1 · The policy kink\n",
    "\n",
    "Weekly UI benefits are 50% of previous weekly earnings up to a maximum of \\$500, reached at earnings of \\$1,000. What is the slope change of the schedule at \\$1,000?\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Left slope: 0.5. Right slope: 0 (benefit capped).\n",
    "\n",
    "**Step 2.** Change: $0 - 0.5 = -0.5$.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 2 · An RKD estimate\n",
    "\n",
    "Unemployment duration rises with earnings at 0.2 weeks per \\$100 of earnings below the kink and 0.1 weeks per \\$100 above. Estimate the effect of \\$100 more in weekly benefit on duration.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Slope change of duration: $0.1 - 0.2 = -0.1$ weeks per \\$100 of earnings.\n",
    "\n",
    "**Step 2.** Slope change of benefits: $-0.5$ dollars per dollar, i.e. $-50$ dollars of benefit per \\$100 of earnings.\n",
    "\n",
    "**Step 3.** $\\hat\\tau = -0.1/(-50) = 0.002$ weeks per dollar of weekly benefit, i.e. 0.2 weeks per \\$100 of benefit.\n",
    "\n",
    "**Answer:** \\$100 more in weekly benefits lengthens unemployment by about 0.2 weeks.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 3 · Why noisier?\n",
    "\n",
    "Why are RKD estimates usually less precise than RD estimates from the same sample?\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** RD estimates a level; RKD estimates a derivative, which needs the spread of $X$ within the window to be large.\n",
    "\n",
    "**Answer:** slope variance scales like $1/(nh^3)$; with the small bandwidths needed near the kink, it is large.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 4 · Normalising cutoffs\n",
    "\n",
    "Three states award a scholarship at test scores of 60, 65 and 70. How can the cutoffs be pooled?\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Define $\\tilde X = X - c_j$ for a student in state $j$; all cutoffs are at $\\tilde X = 0$.\n",
    "\n",
    "**Step 2.** Estimate one RD on $\\tilde X$, or separate RDs per state and average.\n",
    "\n",
    "**Answer:** the pooled estimate is a weighted average of state-specific effects, weighted by the density of students near each cutoff.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 5 · A school-district boundary\n",
    "\n",
    "Houses on either side of a school-district boundary sell at different prices. Name two reasons the price gap may not reflect school quality.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Other services or taxes change at the same boundary (property taxes, policing).\n",
    "\n",
    "**Step 2.** The boundary may follow a road, river or neighbourhood divide that itself affects prices; sorting of households changes neighbourhood composition.\n",
    "\n",
    "</details>\n",
    "\n",
    "## Part 2 · Proofs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 6 · RKD identification\n",
    "\n",
    "Let $Y = \\beta B + m(X) + \\varepsilon$ with $E[\\varepsilon \\mid X]$ having a continuous derivative, $m$ differentiable, and $B = b(X)$ kinked at $c$. Prove $\\tau_{RKD} = \\beta$.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** $E[Y \\mid X = x] = \\beta b(x) + m(x) + E[\\varepsilon \\mid X = x]$.\n",
    "\n",
    "**Step 2.** Derivative: $\\beta b'(x) + m'(x) + \\frac{d}{dx}E[\\varepsilon \\mid X = x]$.\n",
    "\n",
    "**Step 3.** The last two terms are continuous at $c$; the slope change is $\\beta(b'(c^+) - b'(c^-))$.\n",
    "\n",
    "**Step 4.** Divide by the policy's slope change. $\\blacksquare$\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 7 · Fuzzy RKD\n",
    "\n",
    "If actual benefits $B$ deviate from $b(X)$ by noise unrelated to $Y$, show $\\tau$ equals the outcome slope change divided by the slope change of $E[B \\mid X]$.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** $E[Y \\mid X] = \\beta E[B \\mid X] + m(X) + E[\\varepsilon \\mid X]$.\n",
    "\n",
    "**Step 2.** Differentiate and take the change at $c$: $\\Delta\\text{slope}_Y = \\beta\\,\\Delta\\text{slope}_{E[B \\mid X]}$.\n",
    "\n",
    "**Step 3.** Divide. $\\blacksquare$\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 8 · Variance of a slope estimate\n",
    "\n",
    "With $X - c$ uniform on $[0, h]$, $n_h \\approx nf(c)h$ observations and error variance $\\sigma^2$, show that the variance of the OLS slope in a local linear fit is of order $\\sigma^2/(nf(c)h^3)$.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** OLS slope variance: $\\sigma^2/(n_h\\operatorname{Var}(X))$.\n",
    "\n",
    "**Step 2.** $\\operatorname{Var}(X) = h^2/12$ for a uniform on $[0, h]$.\n",
    "\n",
    "**Step 3.** $\\sigma^2/(nf(c)h \\cdot h^2/12) = 12\\sigma^2/(nf(c)h^3)$. $\\blacksquare$\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 9 · Pooling cutoffs\n",
    "\n",
    "With cutoff-specific effects $\\tau_j$ and $n_j$ observations near each cutoff, show that a pooled sharp RD on the normalised running variable estimates approximately $\\sum_j w_j\\tau_j$ with $w_j \\propto n_j$ (when the regression functions have the same slopes).\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Near $\\tilde X = 0$, the pooled right limit is the $n_j$-weighted average of the right limits, and likewise the left.\n",
    "\n",
    "**Step 2.** Subtract: the pooled jump is $\\sum_j(n_j/\\sum_k n_k)\\tau_j$. $\\blacksquare$ If slopes differ by cutoff, cutoff-specific fits are needed.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 10 · A coinciding kink\n",
    "\n",
    "Suppose the tax schedule also has a kink at the same earnings level, so that $m(X)$ has a slope change $\\kappa$ at $c$. Show the RKD estimate becomes $\\beta + \\kappa/\\Delta b'$.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** The outcome slope change becomes $\\beta\\Delta b' + \\kappa$.\n",
    "\n",
    "**Step 2.** Divide by $\\Delta b'$. $\\blacksquare$ Any other policy kinked at the same point is a confounder for RKD, as a coinciding jump is for RD.\n",
    "\n",
    "</details>\n",
    "\n",
    "## Part 3 · Applied"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 11 · UI benefits and unemployment duration\n",
    "\n",
    "Using administrative records on 100,000 claimants, an RKD estimate implies that \\$100 more in weekly benefits lengthens unemployment by 0.2 weeks (Exercise 2). At a typical benefit of \\$450 and duration of 18 weeks, compute the elasticity of duration with respect to benefits.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** A 1% rise in benefits is \\$4.50, lengthening duration by $0.2 \\times 4.5/100 = 0.009$ weeks.\n",
    "\n",
    "**Step 2.** As a share of 18 weeks: $0.009/18 = 0.05\\%$.\n",
    "\n",
    "**Step 3.** Elasticity: $\\varepsilon = (\\Delta D/D)/(\\Delta B/B) = (0.009/18)/0.01 = 0.05$.\n",
    "\n",
    "**Answer:** about 0.05, a small elasticity: at this margin, benefits barely lengthen unemployment.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 12 · School quality and house prices\n",
    "\n",
    "Across attendance-zone boundaries, houses on the side with schools scoring 5% higher on tests sell for 2.5% more, with houses within 0.2 miles of the boundary and boundary fixed effects. Interpret and give one robustness check.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Elasticity of house prices to school test scores ≈ $2.5/5 = 0.5$.\n",
    "\n",
    "**Step 2.** Check: house and neighbourhood characteristics (size, age, demographics) should be balanced across the boundary; prices just outside the boundary in placebo directions should not jump.\n",
    "\n",
    "**Answer:** parents value school quality capitalised at about half the percentage test-score gap.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 13 · Pooling state scholarship cutoffs\n",
    "\n",
    "Three states' scholarship RDs give effects on enrolment of 0.10, 0.06 and 0.04 with 2,000, 1,000 and 1,000 students near the cutoffs. Compute the pooled effect.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Weights 0.5, 0.25, 0.25.\n",
    "\n",
    "**Step 2.** $0.5(0.10) + 0.25(0.06) + 0.25(0.04) = 0.05 + 0.015 + 0.01 = 0.075$.\n",
    "\n",
    "**Answer:** 7.5 points; the spread across states suggests effects depend on the cutoff level or state context.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 14 · RD in time: driving restrictions\n",
    "\n",
    "A city bans cars with certain plate numbers from driving on given weekdays starting on 1 March. Hourly pollution readings around that date are used to estimate the effect. List three concerns.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Other changes at the same date (season, weather, other regulations).\n",
    "\n",
    "**Step 2.** Adaptation: drivers buy second cars or shift trips over weeks, so short-run and long-run effects differ.\n",
    "\n",
    "**Step 3.** Serial correlation in hourly pollution makes conventional standard errors far too small.\n",
    "\n",
    "**Answer:** treat it as an interrupted time series: control for weather and season, check placebo dates, use autocorrelation-robust inference, and look at longer windows.\n",
    "\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 15 · An RKD in a simulation\n",
    "\n",
    "In the simulation below, a benefit schedule with slope 0.5 is capped at $X = 0$; the true effect of benefits on the outcome is 0.8. Compare RKD estimates with local linear and local quadratic fits.\n",
    "\n",
    "<details><summary>Show solution</summary>\n",
    "\n",
    "**Step 1.** Local linear: mean about 0.43, badly biased, because the curvature of $m(X)$ within the bandwidth contaminates the slopes.\n",
    "\n",
    "**Step 2.** Local quadratic: mean about 0.82, close to the truth, but with an SD near 1.2, four times larger.\n",
    "\n",
    "**Answer:** RKD is feasible but fragile: slopes need flexible fits, and flexible fits need very large samples.\n",
    "\n",
    "</details>\n",
    "\n",
    "## Verify in Python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Your work:*"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "print(\"Ex 2:\", -.1 / -50, \"weeks per $ ->\", -.1 / -50 * 100, \"weeks per $100\", \" Ex 11 elasticity:\", round((.2 * 4.5 / 100 / 18) / .01, 3),\n",
    "      \" Ex 13:\", .5 * .10 + .25 * .06 + .25 * .04)\n",
    "\n",
    "rng = np.random.default_rng(78)\n",
    "def kink_slope(x, y, h, p):\n",
    "    out = []\n",
    "    for side in (x >= 0, x < 0):\n",
    "        xx, yy = x[side], y[side]; w = np.clip(1 - np.abs(xx) / h, 0, None); m = w > 0\n",
    "        X = np.column_stack([xx[m] ** k for k in range(p + 1)]); W = w[m]\n",
    "        out.append(np.linalg.solve(X.T @ (W[:, None] * X), X.T @ (W * yy[m]))[1])\n",
    "    return out[0] - out[1]\n",
    "res = {1: [], 2: []}\n",
    "for _ in range(300):\n",
    "    x = rng.uniform(-1, 1, 50_000)\n",
    "    B = .5 * np.minimum(x, 0) + 2                     # benefit: slope 0.5 below the cap, 0 above\n",
    "    y = .8 * B + np.sin(1.5 * x) + .3 * x ** 2 + rng.normal(0, 1, x.size)\n",
    "    for p in (1, 2):\n",
    "        res[p].append(kink_slope(x, y, .4, p) / (0 - .5))\n",
    "for p in (1, 2):\n",
    "    print(f\"local {'linear' if p == 1 else 'quadratic'}: mean {np.mean(res[p]):.3f}  sd {np.std(res[p]):.3f}  (truth 0.8)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Key takeaways\n",
    "\n",
    "- RKD uses a change in a policy's slope: effect = (change in outcome slope) / (change in policy slope), under smoothness of everything else.\n",
    "- Slopes are harder to estimate than levels (variance ∝ 1/(nh³)); RKD needs large data sets.\n",
    "- Multiple cutoffs, geographic boundaries and RD in time extend the design, each with its own threats: coinciding policies, sorting, adaptation and serial correlation."
   ]
  }
 ]
}