MEDSC — Mediation Analysis Synthetic Control (Mellace & Pasquini 2022)#
- Estimator:
Mediation Analysis Synthetic Control (MEDSC) —
mlsynth.MEDSC- Source:
Mellace, G., & Pasquini, A. (2022), “Identification and estimation of mediation effects with a synthetic control” [MellacePasquini2022].
- Replication type:
Path A — the paper’s Proposition 99 empirical decomposition, reproduced on the CDC / Orzechowski-Walker Tax Burden on Tobacco data.
- Status:
Verified — the novel cross-world direct effect matches Table 1 nearly cell for cell; the indirect price channel reproduces its qualitative shape (zero at intervention, growing negative), at a magnitude set by the outcome- path total effect.
Path A — Proposition 99 and the price channel#
California’s Proposition 99 (1989) raised cigarette taxes and funded tobacco control. The classic synthetic-control result is that it cut per-capita sales by roughly a pack and a half by 2000. Mellace and Pasquini ask how much of that ran through the retail price of cigarettes — the direct tax channel — versus everything else the program did. The mediator is the tax-inclusive average cost per pack; the outcome is pack sales per capita.
The data ship as basedata/prop99_mediation.csv (51 units — all 50 states
plus the District of Columbia — over 1970-2000, with cigsale and the
tax-inclusive price), a slim panel drawn from the Tax Burden on Tobacco
file. It carries the seven high-tax states that Abadie’s curated Proposition 99
pool drops, because the direct effect needs them.
import pandas as pd
from mlsynth import MEDSC
df = pd.read_csv("basedata/prop99_mediation.csv")
program = ["Massachusetts", "Arizona", "Oregon", "Florida",
"District of Columbia"]
tax = ["Alaska", "Hawaii", "Maryland", "Michigan", "New Jersey",
"New York", "Washington"]
allstates = sorted(df["state"].unique())
direct_pool = [s for s in allstates if s not in ["California"] + program]
total_pool = [s for s in direct_pool if s not in tax]
df = df[df["state"].isin(["California"] + direct_pool)].copy()
df["treated"] = ((df["state"] == "California") & (df["year"] >= 1989)).astype(int)
res = MEDSC({"df": df, "outcome": "cigsale", "mediator": "price",
"treat": "treated", "unitid": "state", "time": "year",
"total_donors": total_pool, "direct_donors": direct_pool,
"display_graphs": False}).fit()
The two pools are the crux. The total effect uses California’s 38 classic donor states. The direct effect adds the seven high-tax states back (45 donors), because California’s post-1989 price rose above every classic donor’s — without the high-price states, no convex combination of donors can match California’s mediator path and the cross-world control would extrapolate.
The reproduced cross-world direct effect against Table 1:
Year |
Direct effect (mlsynth) |
Mellace-Pasquini (2022) |
|---|---|---|
1995 |
\(-16.8\) |
\(-16.77\) |
2000 |
\(-18.0\) |
\(-17.28\) |
The direct effect — the paper’s novel estimand — reproduces almost exactly. The indirect (price) channel reproduces its shape: essentially zero at the 1989 intervention (\(+0.25\)) and growing negative thereafter, reaching \(-8.8\) by 2000. The direct effect is the larger of the two channels throughout, and the indirect channel opens gradually as the price gap between California and its synthetic widens.
Why the indirect magnitude is smaller than the paper’s#
The paper reports an indirect effect of \(-14.31\) by 2000; mlsynth’s outcome-path fit gives \(-8.8\). The gap is entirely in the total effect, not in the mechanism. Because the indirect channel is total minus direct, and the direct effect matches the paper, any difference in the indirect effect is inherited one for one from the total effect:
Quantity (2000) |
mlsynth |
Mellace-Pasquini |
note |
|---|---|---|---|
Total |
\(-26.8\) |
\(-31.59\) |
the difference |
Direct |
\(-18.0\) |
\(-17.28\) |
matches |
Indirect |
\(-8.8\) |
\(-14.31\) |
inherits the total gap |
mlsynth’s total effect of \(-26.8\) tracks the canonical Abadie synthetic
control (about \(-26\) by 2000 on the outcome-path fit); the paper’s
\(-31.59\) is a larger effect that comes from its cross-validated predictor
weights over a specific set of special predictors (lagged outcomes, a lagged
price and three covariates). Chasing that larger total by adding those
predictors and cross-validated weights was found to reproduce the total more
closely but to distort the direct/indirect split — the collinear covariates
pull the cross-world match away from the mediator path. The default outcome-path
specification is the one under which the decomposition mechanism reproduces, so
it is the one the benchmark pins. The covariate (mscmt) backend remains
available for users who want to trade a closer total against a looser split.
The honest reading is that the mediation mechanism — a cross-world control that matches the treated mediator path, yielding a direct effect near the paper’s and an indirect channel that opens at zero and grows — reproduces cleanly; the exact Table 1 total, and hence the exact indirect magnitude, depends on a predictor tuning that is orthogonal to the mediation contribution.
Seam notes#
Three details were pinned while porting, and each is held by a unit test:
Two donor pools. The total and direct effects draw on different donor sets — the direct pool adds the high-mediator states the total pool excludes — so the cross-world control can span the treated unit’s post-treatment mediator. MEDSC exposes
total_donorsanddirect_donorsfor exactly this; both default to every non-treated unit.Per-period re-estimation. The direct effect is refit separately for each post period, matching the mediator path only up to that period. Matching the whole post-treatment mediator path at once — or reusing a single set of weights — collapses the indirect channel toward zero.
The 3/4 – 1/4 predictor split. The direct fit places three-quarters of the predictor weight on the pre-treatment constraints and one-quarter, split equally, on the post-treatment mediator constraints (
pre_weight). This is the paper’s weighting; it keeps the pre-treatment fit intact while still binding the mediator match.