*! version 2.1.0 5 Oct 2023
help synth2

Title

synth2 -- Implementation of synthetic control method (SCM) with placebo tests, robustness test and visualization

Syntax

synth2 depvar indepvars,
trunit(#)
trperiod(#)
[options]

Model
counit(numlist:numlist) control units to be used as the donor pool

preperiod(numlist:numlist) pretreatment periods before the intervention occurred

postperiod(numlist:numlist) posttreatment periods when and after the intervention occurred

xperiod(numlist:numlist) periods over which the covariates specified in indepvars are averaged

mspeperiod(numlist:numlist) periods over which the mean squared prediction error (MSPE) should be minimized

nested fully nested optimization procedure that searches among all (diagonal) positive semidefinite V-matrices and sets of W-weights

allopt gaining fully robust results if nested is specified

customV(numlist) supply custom V-Weights which determines the predictive power of the variable for the outcome over the pretreatment periods

Optimization
margin(real) margin for constraint violation tolerance

maxiter(#) maximum number of iterations

sigf(#) precision (number of significant figures)

bound(#) clipping bound for the variables

Placebo Tests
placebo([{unit|unit(numlist)} period(numlist) cutoff(#_c) show(#_s)]) in-space placebo test using fake treatment units and/or in-time placebo test using a fake treatment time

Robustness Test
loo Robustness test that excludes one unit in the donor pool with nonzero weight

Reporting
frame(framename) create a Stata frame storing dataset with generated variables including counterfactual predictions, treatment effects,
and results from placebo tests and/or robustness test if implemented

symbol(symboltype) change the symbol type of generated variables in Stata frame

nofigure Do not display figures. The default is to display all figures.

savegraph([prefix], [asis replace]) Save all produced graphs to the current path.

xtset panelvar timevar must be used to declare a balanced panel dataset in the usual long form; see [XT] xtset.

depvar and indepvars must be numeric variables, and abbreviations are not allowed.

Description

As a wrapper program for synth implementing synthetic control method (SCM), synth2 provides convenient utilities to automate in-space placebo test using fake treatment units,
in-time placebo test using a fake treatment time, and leave-one-out robustness test that excludes one control unit with nonzero weight at a time.
synth2 produces a series of graphs for visualization along the way.
The command synth (available from Statistical Software Components) is required.
See Yan and Chen (2023) for more details.

Required Settings

trunit(#) the unit number of the treated unit (i.e., the unit affected by the intervention) as given in the panel variable specified in xtset panelvar.
Note that only a single unit number can be specified.

trperoid(#) the time period when the intervention occurred.
The time period refers to the time variable specified in xtset timevar, and must be an integer (see examples below).
Note that only a single time period can be specified.

Options

Model

counit(numlist:numlist) a list of unit numbers for the control units as numlist given in the panel variable specified in xtset panelvar.
The list of control units specified constitute what is known as the "donor pool". If no counit is specified,
the donor pool defaults to all available units other than the treated unit.
The previous option ctrlunit(numlist:numlist) is deprecated, but continues to work just like the current option counit(numlist:numlist).

preperiod(numlist:numlist) a list of pretreatment periods as numlist given in the time variable specified in xtset timevar.
If no preperiod is specified, preperiod defaults to the entire pre-intervention period,
which ranges from the earliest time period available in the time variable to the period immediately prior to the intervention.

postperiod(numlist:numlist) a list of posttreatment periods (when and after the intervention occurred) as numlist given in the time variable specified in xtset timevar.
If no postperiod is specified, postperiod defaults to the entire post-intervention period,
which ranges from the time period when the intervention occurred to the latest time period available in the time variable.

xperiod(numlist:numlist) a list of periods as numlist given in the time variable specified in xtset timevar, over which the covariates specified in indepvars are averaged.

mspeperiod(numlist:numlist) a list of pretreatment periods as numlist given in the time variable specified in xtset timevar,
over which the mean squared prediction error (MSPE) should be minimized.

nested if nested is specified, synth2 embarks on a fully nested optimization procedure,
which achieves better accuracy than the default algorithm at the expense of additional computing time.
For details, see synth.

allopt if nested is specified, the user can also specify allopt if she or he is willing to trade-off even more computing time in order to gain fully robust results.
allopt provides a robustness check by running the nested optimization three times using three different starting points,
and returns the best result.
For details, see synth.

customV(numlist:numlist) a list of custom V-weights as numlist appearing in the same order as the covariates listed in indepvars to replace the data-driven V-weights.
For details, see synth.

Optimization

The constrained quadratic optimization routine is based on an algorithm that uses the interior point method to solve the constrained quadratic programming problem (see Vanderbei 1999 for more details on the interior point method).
It is implemented via a C++ plugin and has the following tuning parameters:

margin(real) margin for constraint violation tolerance. The default is 5 percent (i.e., 0.05).

maxiter(#) maximum number of iterations. The default is 1000.

sigf(#) precision (nnumber of significant figures). The default is 7.

bound(#) clipping bound for the variables. The default is 10.

If nested is specified, a nested optimization will be performed using the constrained quadratic programming routine and Stata's ml optimizer.
By default, synth2 uses the maximize default settings.
The user may tune the maximize settings depending on his application (e.g., like synth2 ... , iterate(20)).

Placebo Tests

placebo([{unit|unit(numlist)} period(numlist) cutoff(#_c) show(#_s)]) specifies the types of placebo tests to be performed; otherwise, no placebo test will be implemented.

{unit|unit(numlist)} specifies the in-space placebo test using fake treatment units in the donor pool,
where unit uses all fake treatment units and unit(numlist) uses a list of fake treatment units specified by numlist.
These two options iteratively reassign the treatment to control units where no intervention actually occurred,
and calculate the p-values of the treatment effects. Note that only one of unit and unit(numlist) can be specified.

period(numlist:numlist) specifies the in-time placebo test using fake treatment times (more than one fake treatment time can be specified).
This option reassigns the treatment to time periods previous to the intervention, when no treatment actually occurred.

cutoff(#_c) specifies a cutoff threshold that discards fake treatment units with pretreatment MSPE #_c times larger than that of the treated unit,
where #_c must be a real number greater than or equal to 1.
This option only applies when unit or unit(numlist) is specified.
If this option is not specified, then no fake treatment units are discarded.

show(#_s) specifies the number of units to show in the post/pre MSPE graph, which correponds to units with the largest #_s ratios of posttreatment MSPE to pretreatment MSPE.
This option only applies when unit or unit(numlist) is specified.
If this option is not specified, the default is to show post/pre MSPE ratios for all units.

Robustness Test

loo specifies the leave-one-out robustness test that excludes one control unit with a nonzero weight at a time.
synth2 iteratively re-estimates the model omitting one unit in each iteration that receives a positive weight.
By excluding a unit receiving a positive weight goodness of fit is sacrificed, but this sensitivity check can evaluate to what extent results are driven by any particular control unit.

Reporting

frame(framename) creates a Stata frame storing generated variables in the wide form including counterfactual predictions,
treatment effects, and results from placebo tests and/or robustness test if implemented. The frame named framename is replaced if it already exists, or created if not.

symbol(symboltype) specifies signtype as the symbol type for generated variables in Stata frame framename.
signtype can be set to either 1 (default) or 2, correponding to the symbols "·" or "_", respectively.

nofigure Do not display figures. The default is to display all figures from the estimation results,
placebo tests and robustness test if available.

savegraph([prefix], [asis replace]) automatically and iteratively calls the graph save to save all produced graphs to the current path,
where prefix specifies the prefix added to _graphname to form a file name, that is, the graph named graphname is stored as prefix_graphname.gph.
asis and replace are options passed to graph save; for details, see [G-2] graph save.
Note that this option only applies when nofigure is not specified.

Example: estimating the effect of California's tobacco control program (Abadie, Diamond, and Hainmueller 2010)

. use smoking, clear

. xtset state year

* Replicate results in Abadie, Diamond, and Hainmueller (2010)

. synth2 cigsale lnincome age15to24 retprice beer cigsale(1988) cigsale(1980) cigsale(1975), trunit(3) trperiod(1989) xperiod(1980(1)1988) nested allopt

* Implement in-space placebo test using fake treatment units with pretreatment MSPE 2 times smaller than or equal to that of the treated unit

* For illustration, we drop the "allopt" option to save time. The "allopt" option is recommended for the most accurate results if time permits

* To assure convergence, we change the default option "sigf(7)" (7 significant figures) to "sigf(6)".

. synth2 cigsale lnincome age15to24 retprice beer cigsale(1988) cigsale(1980) cigsale(1975), trunit(3) trperiod(1989) xperiod(1980(1)1988) nested placebo(unit cut(2)) sigf(6)

* Implement in-time placebo test using the fake treatment time 1985 and dropping the covariate cigsale(1988)

. synth2 cigsale lnincome age15to24 retprice beer cigsale(1980) cigsale(1975), trunit(3) trperiod(1989) xperiod(1980(1)1984) nested placebo(period(1985))

* Implement leave-one-out robustness test, create a Stata frame "california" storing generated variables,
and save all produced graphs to the current path

. synth2 cigsale lnincome age15to24 retprice beer cigsale(1988) cigsale(1980) cigsale(1975), trunit(3) trperiod(1989) xperiod(1980(1)1988) nested loo frame(california) savegraph(california, replace)

* Combine all produced graphs

. graph combine `e(graph)', cols(2) altshrink

* Change to the generated Stata frame "california"

. frame change california

* Change back to the default Stata frame

. frame change default

Stored results

synth2 stores the following in e():

Scalars

e(N) number of observations

e(T0) number of pretreatment periods

e(T1) number of posttreatment periods

e(K) number of covariates

e(rmse) root mean squared error of the model fitted in the pretreatment period

e(r2) R-squared of the model fitted over the oosttreatment period

e(att) average treatment effect

Macros

e(panelvar) name of the panel variable

e(timevar) name of the time variable

e(varlist) names of the dependent variable and independent variables

e(depvar) name of the dependent variable

e(indepvars) names of independent variables (covariates)

e(unit_all) all units

e(unit_tr) treatment unit

e(unit_ctrl) control units

e(time_all) entire periods

e(time_tr) treatment period

e(time_pre) pretreatment periods

e(time_post) posttreatment periods

e(frame) name of Stata frame storing generated variables

e(graph) names of all produced graphs

Matrices

e(V_wt) diagonal matrix V containing the optimal covariate weights in the diagonal

e(U_wt) vector w that contains the optimal unit weights

e(bal) matrix containing sample averages for the treated unit,
synthetic control unit and control units

e(mspe) matrix containing pretreatment MSPE, posttreatment MSPE, ratios of posttreatment MSPE to pretreatment MSPE, and ratios of pretreatment MSPE of control units to that of the treated unit

e(pval) matrix containing estimated treatment effects and p-values from placebo tests using fake treatment units

Reference

Abadie, A., A. Diamond, and J. Hainmueller. 2015. Comparative Politics and the Synthetic Control Method.
American Journal of Political Science 59(2): 495-510.

Abadie, A., A. Diamond, and J. Hainmueller. 2011. SYNTH: Stata module to implement Synthetic Control Methods for Comparative Case Studies.
Statistical Software Components, Boston College Department of Economics.

Abadie, A., A. Diamond, and J. Hainmueller. 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. and Gardeazabal, J. 2003. Economic Costs of Conflict: A Case Study of the Basque Country.
American Economic Review 93(1): 113-132.

Yan, G. and Chen, Q. 2023. synth2: Synthetic Control Method with Placebo Tests, Robustness Test and Visualization. The Stata Journal 23(3): 597-624.

Author

Guanpeng Yan, Shandong University, CN

guanpengyan@yeah.net

Qiang Chen, Shandong University, CN

qiang2chen2@126.com

www.econometrics-stata.com

Also see

Help: synth (SSC), allsynth (SSC, if installed), synth_runner (SSC, if installed), and scul(SSC, if installed).