*! version 1.0.0 24apr2026

Title

multisynth -- build synthetic clones for treated panel units

Syntax

multisynth yvar [if] [in],
unit(unitvar)
time(timevar)
treated(treatedvar)
post(postvar)
[controls(varlist)
ctrlweight(#)
saving(filename)
replace
wsaving(filename)
wreplace
graph]

Description

multisynth extends the synthetic-control method of Abadie, Diamond, and
Hainmüller (2010) to panel settings with multiple treated units and staggered
treatment timing. The synthetic-control idea — finding a convex combination of
untreated units that reproduces the treated unit's pre-treatment outcome path —
is applied independently to each treated unit. Treated units are identified by
treated()==1; the variable post() defines the unit-specific split
between pre-treatment and post-treatment observations, so units need not share
a common treatment date.

Three aspects differ from the original synth command. First, treatment
timing is unit-specific: multisynth reads the treatment date from
post() for each unit separately, so staggered adoption requires no
special handling. Second, optimisation uses gradient descent with a softmax
reparameterisation of the donor weights rather than constrained quadratic
programming; this scales to many units without a QP solver, at the cost of
local rather than global convergence (rarely a practical issue with the softmax
surface). Third, the output is an augmented stacked panel appended in memory
and optionally saved with saving(), so the dataset is immediately usable
in reghdfe, xtreg, or any event-study estimator without further
post-processing.

multisynth is a data-preparation command. It constructs synthetic clones
and reports pre-treatment fit quality (RMSPE and R-squared per treated unit)
but does not estimate treatment effects. For treatment-effect estimation, run
a second-stage regression on the augmented panel. For single high-stakes case
studies requiring placebo inference and a globally optimal solution, the
original synth command remains the appropriate tool.

The command appends one synthetic clone to the data for each treated unit.
It generates a binary clone indicator, a binary donor indicator,
a source_unit variable, and a unique analysis identifier ms_id.

Options

unit(unitvar) specifies the numeric panel unit identifier.

time(timevar) specifies the panel time variable. The command
uses the within-unit ordering of this variable.

treated(treatedvar) specifies the unit-level treatment
indicator. It must be 1 for ever-treated units and 0 for never-treated units,
and it must be constant within unit.

post(postvar) specifies the unit-specific post-treatment
indicator. It must be 0 before treatment and 1 from first treatment onward.

controls(varlist) supplies optional control variables.
If omitted, multisynth uses only the outcome path.

ctrlweight(#) sets the weight on the control-balance penalty.
The default is 0.25. Set ctrlweight(0) for a pure outcome-driven
synthetic clone when controls are supplied but should not affect matching.

saving(filename) saves the stacked treated-versus-synthetic
panel to filename.

replace allows overwriting an existing file named in saving().

wsaving(filename) saves a wide-format donor-weight dataset
with one row per treated unit. Columns are source_unit, then pairs
donor_k and w_k ordered by weight descending, followed
by pre_rmspe (root mean squared prediction error of the pre-treatment
synthetic fit) and pre_r2 (R-squared of the pre-treatment fit).

wreplace allows overwriting an existing file named in wsaving().

graph produces an average event-time graph comparing the mean observed
treated outcome with the mean synthetic outcome across all treated units.
Event time skips 0, so the treatment shock lies between -1 and 1 and the
graph draws a reference line at 0.

Created variables

After multisynth runs, the dataset in memory contains the original rows
plus appended clone rows. Key created variables are:

- clone: 1 for synthetic clone rows, 0 otherwise

- donor: 1 for original never-treated donor rows, 0 for treated and clone rows

- source_unit: treated unit that the row belongs to; for original rows it equals unit()

- ms_id: unique identifier for original and clone units in the augmented data

- event_time: periods relative to treatment onset; negative values are
pre-treatment, positive values are post-treatment; 0 is skipped so the gap
between -1 and 1 marks the treatment shock

Remarks

Version 1.0 requires numeric unit IDs and complete donor support over each
treated unit's observed time path. It does not yet report placebo inference,
standard errors, or second-stage treatment estimates.

The donor pool consists of all units with treated()==0 that have
complete observations over the treated unit's full time span. Units with
any missing values in yvar or controls() during that span are
excluded from the donor pool for that treated unit.

Examples

. use multisynth_example_data, clear

. multisynth y, unit(id) time(year) treated(treated) post(post)

. multisynth y, unit(id) time(year) treated(treated) post(post) controls(x1 x2 x3)

. multisynth y, unit(id) time(year) treated(treated) post(post) ///
controls(x1 x2) ctrlweight(0.2) saving(stack.dta) replace ///
wsaving(weights.dta) wreplace graph

Returned results

multisynth returns:

- r(treated_units_total): number of ever-treated units in the sample

- r(treated_units_completed): treated units for which a clone was built

- r(treated_units_skipped): treated units skipped due to insufficient donor support

- r(ctrlweight): control-balance penalty weight used

- r(clone_units_added): number of synthetic clones appended

- r(saved_file): path to augmented panel file, if saving() was used

- r(wsaved_file): path to weights file, if wsaving() was used

References

Abadie, A., Diamond, A., and Hainmüller, J. 2010. Synthetic control methods
for comparative case studies: Estimating the effect of California's tobacco
control program. Journal of the American Statistical Association
105(490): 493–505.

Abadie, A., Diamond, A., and Hainmüller, J. 2011. synth: Stata command
for synthetic control methods. Statistical Software Components S457603,
Boston College Department of Economics.

Author

Leonhard Benedikt Friedel

WHU - Otto Beisheim School of Management

leonhard.friedel@whu.edu

Also see

synth (if installed)

xtset