2  Five Estimands on One DGP

Before choosing an estimator, we need to know the estimand. ATE, ATT, LATE, CATE and QTE are not five ways to estimate the same object. They are five different objects.

Here I use one simulated data set so we can calculate all of them. The simulation is useful because we observe both potential outcomes. In real data we do not, which is exactly why identification assumptions matter.

2.1 The data-generating process

We draw \(n = 20{,}000\) people. Each has an observed covariate \(X_i \sim U(0,1)\), an unobserved type \(U_i \sim N(0,1)\), and a randomly assigned offer \(Z_i \sim \text{Bernoulli}(0.5)\). The offer is the instrument. It raises the probability of treatment but does not enter the outcome. The treatment probabilities are \(P(D=1 \mid Z=0, U) = 0.10 + 0.20U\) and \(P(D=1 \mid Z=1, U) = 0.10 + 0.20U + 0.50\), both clipped to \([0,1]\). One uniform draw \(V_i\) is compared against both thresholds, so \(D_i(1) \ge D_i(0)\) for every unit and there are no defiers. The potential outcomes are \(Y_i(0) = 0.5X_i + 0.3U_i + \varepsilon_i\) with \(\varepsilon_i \sim N(0,1)\), and \(Y_i(1) = Y_i(0) + \tau(X_i)\) with \(\tau(x) = 1 + 2x\). We observe \(D_i = Z_i D_i(1) + (1-Z_i) D_i(0)\) and \(Y_i = D_i Y_i(1) + (1-D_i) Y_i(0)\).

Two features of this design drive everything below. Selection into treatment runs through \(U\) and \(V\), never through \(X\). The treatment effect runs through \(X\) alone. And \(X\) is drawn independently of \(U\), \(V\) and \(Z\).

Code
set.seed(42)
n <- 20000

X <- runif(n, 0, 1)        # observed covariate, in [0,1]
U <- rnorm(n)              # latent type, unobserved
Z <- rbinom(n, 1, 0.5)    # random instrument

# Treatment assignment: depends on Z (the instrument) and U (selection on type)
# Higher U → more likely to take treatment regardless of Z (always-takers)
# Lower  U → less likely to take treatment regardless of Z (never-takers)
# Middle U → responsive to Z (compliers)
pD0 <- pmin(pmax(0.10 + 0.20 * U,        0), 1)  # P(D=1 | Z=0, U)
pD1 <- pmin(pmax(0.10 + 0.20 * U + 0.50, 0), 1)  # P(D=1 | Z=1, U) — adds 0.50

# One latent draw V per person, thresholded against both probabilities.
# Since pD1 >= pD0, V < pD0 implies V < pD1, so D1 >= D0 for every unit:
# monotonicity (no defiers) holds by construction, as the LATE theorem requires.
V  <- runif(n)
D0 <- as.integer(V < pD0)   # potential treatment if not offered slot
D1 <- as.integer(V < pD1)   # potential treatment if offered slot
D  <- ifelse(Z == 1, D1, D0)

# Heterogeneous treatment effect: depends on X
# Y(d) = baseline + d * tau(X) + 0.3 * U + noise
tau_fn <- function(x) 1.0 + 2.0 * x   # the true individual treatment effect

Y0 <- 0.5 * X + 0.3 * U + rnorm(n)
Y1 <- Y0 + tau_fn(X)
Y  <- ifelse(D == 1, Y1, Y0)

df <- data.frame(X = X, Z = Z, D = D, Y = Y)
head(df)
          X Z D          Y
1 0.9148060 1 1  4.1619422
2 0.9370754 0 0 -0.8962833
3 0.2861395 1 1  1.7657727
4 0.8304476 1 1  3.0306957
5 0.6417455 0 0  0.1362524
6 0.5190959 0 0 -0.2396664

The printed rows are the data an analyst would receive: \(X\), \(Z\), \(D\) and \(Y\). We keep Y0 and Y1 aside, and every “true” number in this chapter is computed from them. With real data each observation reveals only one of the two.

2.2 The five estimands

2.2.1 ATE — average treatment effect

\[ \text{ATE} = \mathbb{E}[Y(1) - Y(0)] \tag{2.1}\]

ATE is the mean effect in the whole population. It compares the mean outcome if everyone were treated with the mean outcome if nobody were treated. Here it is the average of \(\tau(x) = 1+2x\) over \(X \sim U(0,1)\), which is exactly 2. We average the individual effects in the sample and compare.

Code
ate_true <- mean(Y1 - Y0)
cat(sprintf("ATE (population mean of Y1 - Y0) = %.3f\n", ate_true))
ATE (population mean of Y1 - Y0) = 1.996
Code
# Theoretical ATE: integral of (1 + 2x) over Uniform[0,1] = 1 + 1 = 2
cat("Theoretical ATE = integral(1 + 2x)dx on [0,1] = 2.000\n")
Theoretical ATE = integral(1 + 2x)dx on [0,1] = 2.000

The sample average is 1.996 against a population value of 2. The 0.004 gap is simulation noise at \(n = 20{,}000\).

2.2.2 ATT — average treatment effect on the treated

\[ \text{ATT} = \mathbb{E}[Y(1) - Y(0) \mid D = 1] \tag{2.2}\]

ATT is the mean effect for the units that actually took treatment. It differs from ATE when treatment selection is related to treatment-effect heterogeneity. We average the individual effects over the treated units only.

Code
att_true <- mean(Y1[D == 1] - Y0[D == 1])
cat(sprintf("ATT (mean of Y1-Y0 conditional on D=1) = %.3f\n", att_true))
ATT (mean of Y1-Y0 conditional on D=1) = 1.995

ATT is 1.995 against an ATE of 1.996. The two are analytically identical in this DGP, exactly \(2.0\) in the population, so the small difference is simulation noise and not a true gap between the estimands. The reason is mechanical: the individual treatment effect \(\tau_i = 1+2X_i\) depends only on \(X_i\), while selection into treatment depends on \(U_i\) (and the instrument \(Z_i\) below), and \(X_i\) is generated independently of \(U_i\) and \(Z_i\). Since treatment-effect heterogeneity is unrelated to who selects into treatment or who complies with the instrument, averaging \(\tau_i\) over the treated subpopulation or over compliers gives the same population average as over everyone – hence ATE = ATT = LATE = \(2.0\) exactly here. If selection (or compliance) also depended on \(X\), these estimands would diverge, since ATE, ATT, and LATE are different averages of \(\tau_i\) across different, non-identical subpopulations.

2.2.3 LATE — local average treatment effect (Imbens-Angrist)

\[ \text{LATE} = \mathbb{E}[Y(1) - Y(0) \mid D(1) > D(0)] \tag{2.3}\]

LATE is the mean effect for compliers, the units whose treatment status is changed by the instrument. Under the usual IV assumptions, the Wald estimator identifies this effect, not the ATE. Identifying LATE by the Wald ratio additionally requires monotonicity (no defiers): \(D(1) \ge D(0)\) for all \(i\). This DGP imposes it by generating both potential treatments from one shared latent draw \(V_i\) with ordered thresholds (\(D(z) = \mathbb{1}\{V_i < p_{Dz}\}\) with \(p_{D1} \ge p_{D0}\)), so no unit is pushed out of treatment by the offer. Raising the probability alone would not be enough: with independent draws for \(D(0)\) and \(D(1)\), roughly 3% of units would be defiers and the Wald ratio would no longer equal the complier mean.

We know \(D_i(0)\) and \(D_i(1)\) for every unit, so we can label the compliers and average their individual effects directly. We then compute the Wald ratio from \(Y\), \(D\) and \(Z\) alone, which is all an analyst would have, and compare.

Code
compliers <- (D1 == 1) & (D0 == 0)
late_true <- mean(Y1[compliers] - Y0[compliers])
cat(sprintf("LATE (mean of Y1-Y0 conditional on complier status) = %.3f\n", late_true))
LATE (mean of Y1-Y0 conditional on complier status) = 1.999
Code
cat(sprintf("Share of compliers: %.3f\n", mean(compliers)))
Share of compliers: 0.456
Code
# Wald estimator from the data alone
wald <- (mean(Y[Z == 1]) - mean(Y[Z == 0])) /
        (mean(D[Z == 1]) - mean(D[Z == 0]))
cat(sprintf("Wald IV estimate (should match LATE): %.3f\n", wald))
Wald IV estimate (should match LATE): 1.949

Compliers are 45.6% of the sample and their mean effect is 1.999, again the population value of 2. The Wald ratio gives 1.949. The two agree up to sampling noise: the ratio divides a difference in mean outcomes by a treatment rate difference of 0.456, which magnifies the noise in the numerator, and the 0.05 gap is about one standard error of the ratio. With heterogeneous effects IV averages over the people moved by the instrument, and here that group has the same distribution of \(X\) as everyone else.

2.2.4 CATE — conditional average treatment effect

\[ \text{CATE}(x) = \mathbb{E}[Y(1) - Y(0) \mid X = x] \tag{2.4}\]

CATE keeps \(X\) in the estimand. In this DGP, CATE(\(x\)) is simply \(\tau(x)=1+2x\). We cannot condition on a single point of a continuous \(X\) in a finite sample, so we cut \([0,1]\) into 20 equal-width bins, average the individual effects within each bin, and print two of them next to the true \(\tau\) at the bin centre.

Code
nbins <- 20
breaks <- seq(0, 1, length.out = nbins + 1)
centers <- (breaks[-1] + breaks[-(nbins + 1)]) / 2
bin_idx <- cut(X, breaks = breaks, include.lowest = TRUE, labels = FALSE)

cate_est <- tapply(Y1 - Y0, bin_idx, mean)

cat(sprintf("CATE at x=%.3f: estimated %.2f, true %.2f\n",
            centers[4], cate_est[4], tau_fn(centers[4])))
CATE at x=0.175: estimated 1.35, true 1.35
Code
cat(sprintf("CATE at x=%.3f: estimated %.2f, true %.2f\n",
            centers[16], cate_est[16], tau_fn(centers[16])))
CATE at x=0.775: estimated 2.55, true 2.55

The binned averages are 1.35 at \(x = 0.175\) and 2.55 at \(x = 0.775\), matching \(\tau\) at both bin centres to two decimals. The effect at \(x=0.775\) is nearly twice the effect at \(x=0.175\), and no single scalar reports that.

2.2.5 QTE — quantile treatment effect

\[ \text{QTE}(q) = F^{-1}_{Y(1)}(q) - F^{-1}_{Y(0)}(q) \tag{2.5}\]

QTE compares the two marginal outcome distributions. It is the difference between a quantile under treatment and the same quantile under control. It does not follow the same person across the two potential outcomes. We take the quantiles of \(Y(1)\) and of \(Y(0)\) on a grid from 0.05 to 0.95 and difference them, printing the 10th, 50th and 90th percentiles.

Code
qte_grid <- seq(0.05, 0.95, by = 0.05)
qte_est  <- quantile(Y1, qte_grid) - quantile(Y0, qte_grid)

cat(sprintf("QTE(0.10) = %.3f\n", quantile(Y1, 0.10) - quantile(Y0, 0.10)))
QTE(0.10) = 1.709
Code
cat(sprintf("QTE(0.50) = %.3f\n", quantile(Y1, 0.50) - quantile(Y0, 0.50)))
QTE(0.50) = 2.009
Code
cat(sprintf("QTE(0.90) = %.3f\n", quantile(Y1, 0.90) - quantile(Y0, 0.90)))
QTE(0.90) = 2.283

QTE rises from 1.709 at the 10th percentile to 2.009 at the median and 2.283 at the 90th. The reason is that \(\tau(X) = 1+2X\) is largest where \(X\) is large, and \(Y(0) = 0.5X + 0.3U + \varepsilon\) is also increasing in \(X\), so treatment adds most to the units that were already high in the control distribution. Treatment stretches the distribution rather than shifting it. The median QTE happens to sit near the ATE here, and there is no general reason for that.

2.3 When the estimands differ

The three scalar estimands coincided because selection had nothing to do with the effect modifier. We now break that, and see how far apart they move.

The second DGP is the first one with a single change: \(X\) enters the treatment probability, \(P(D=1 \mid Z=0, U, X) = 0.10 + 0.20U + 0.6X\), clipped to \([0,1]\), with the offer adding 0.50 as before. Everything else is unchanged — a fresh sample of \(n = 20{,}000\), \(X \sim U(0,1)\), \(U \sim N(0,1)\), \(Z \sim \text{Bernoulli}(0.5)\), one shared uniform draw for the two potential treatments, \(Y(0) = 0.5X + 0.3U + \varepsilon\) and \(\tau(x) = 1 + 2x\).

Code
set.seed(7)
n2 <- 20000
X2 <- runif(n2, 0, 1)
U2 <- rnorm(n2)
Z2 <- rbinom(n2, 1, 0.5)

# High X → much more likely to take treatment (selection on X, the modifier)
pD0_2 <- pmin(pmax(0.10 + 0.20 * U2 + 0.6 * X2, 0), 1)
pD1_2 <- pmin(pmax(pD0_2 + 0.50,                 0), 1)
V2    <- runif(n2)                  # shared draw → D1_2 >= D0_2, no defiers
D0_2  <- as.integer(V2 < pD0_2)
D1_2  <- as.integer(V2 < pD1_2)
D2    <- ifelse(Z2 == 1, D1_2, D0_2)
Y0_2  <- 0.5 * X2 + 0.3 * U2 + rnorm(n2)
Y1_2  <- Y0_2 + tau_fn(X2)
Y2    <- ifelse(D2 == 1, Y1_2, Y0_2)

ate2  <- mean(Y1_2 - Y0_2)
att2  <- mean(Y1_2[D2 == 1] - Y0_2[D2 == 1])
compliers2 <- (D1_2 == 1) & (D0_2 == 0)
late2 <- mean(Y1_2[compliers2] - Y0_2[compliers2])

cat("Selection-on-X DGP:\n")
Selection-on-X DGP:
Code
cat(sprintf("  ATE  = %.3f\n", ate2))
  ATE  = 2.001
Code
cat(sprintf("  ATT  = %.3f  (now higher: treated have higher X → larger τ)\n", att2))
  ATT  = 2.124  (now higher: treated have higher X → larger τ)
Code
cat(sprintf("  LATE = %.3f  (compliers' mean X drives this)\n", late2))
  LATE = 1.926  (compliers' mean X drives this)

ATE is still 2.001, because the distribution of \(X\) has not moved. ATT rises to 2.124 and LATE falls to 1.926. Since \(\tau = 1 + 2X\), every subgroup average is \(1 + 2\,\mathbb{E}[X \mid \text{subgroup}]\), so the numbers report the subgroups directly: the treated have mean \(X\) of 0.562 and the compliers have mean \(X\) of 0.463, against 0.5 in the population.

The treated are high-\(X\) because high \(X\) raises the treatment probability. The compliers are low-\(X\) for a less obvious reason. The offer adds 0.50 to a probability capped at 1, so a unit with \(p_{D0}\) above 0.5 has a complier window of width \(1 - p_{D0}\), narrower than 0.5. High-\(X\) units are the ones the cap bites on: mean window width falls from 0.49 in the bottom quartile of \(X\) to 0.34 in the top, and the complier rate falls with it, from 0.48 to 0.34. So the instrument moves mostly low-\(X\) units, and LATE lands below ATE.

Here the choice between ATE, ATT and LATE changes the substantive answer.

2.4 Which estimand should you choose?

The estimand should come from the research question:

Policy question Right estimand
“What if we treated everyone?” ATE
“What did treating the currently-treated achieve?” ATT
“What can the instrument tell us?” LATE
“Who benefits most?” CATE(\(x\))
“Does the effect vary across the outcome distribution?” QTE(\(q\))
“What is the distribution of individual effects?” Often unidentifiable; bounds required

It is fine for one paper to report more than one estimand, as long as each is named correctly. What is not fine is to report the coefficient that is easiest to estimate and call it “the causal effect.”

2.5 Summary

  • ATE, ATT and LATE are different averages of the individual treatment effect.
  • CATE(\(x\)) keeps heterogeneity by covariates. QTE(\(q\)) describes changes in the outcome distribution.
  • With heterogeneous effects, IV estimates LATE. It should not be described as ATE unless extra assumptions justify that interpretation. This is the clean case with no covariates. Once we add covariates linearly to 2SLS, even LATE needs a rich covariates condition that is rarely defended. See Blandhol et al. (2025) and the IV chapter section “When 2SLS with Covariates Is Actually LATE”.
  • Estimator choice comes after the estimand is fixed.