| Title: | Synthetic Control Method with Spillover Effects |
|---|---|
| Description: | A general-purpose implementation of synthetic control methods that accounts for potential spillover effects between units. Based on the methodology of Cao and Dowd (2019). |
| Authors: | Jianfei Cao [aut], Zhanchao Fu [cre] |
| Maintainer: | Zhanchao Fu <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.2 |
| Built: | 2026-07-20 05:44:49 UTC |
| Source: | https://github.com/cran/scmSpillover |
Annual per-capita cigarette sales (in packs) for 39 U.S. states from 1970
to 2000. The first column, CA, is California – the treated unit in
the Proposition 99 tobacco-control program, a large excise-tax increase that
took effect in 1989. The remaining 38 columns are control (donor) states.
This is the running example used in the synthetic control literature.
california_cigarettecalifornia_cigarette
A numeric matrix with 31 rows (years 1970-2000) and 39 columns
(U.S. states). Row names are the years; column names are two-letter state
abbreviations, with CA (California) first.
Orzechowski and Walker, The Tax Burden on Tobacco, as used by Abadie, Diamond and Hainmueller (2010) "Synthetic Control Methods for Comparative Case Studies".
data(california_cigarette) dim(california_cigarette) california_cigarette[1:5, 1:4]data(california_cigarette) dim(california_cigarette) california_cigarette[1:5, 1:4]
Generate simulated data for testing
generate_test_data( n_units = 20, n_periods = 30, treatment_start = 20, effect_size = -5 )generate_test_data( n_units = 20, n_periods = 30, treatment_start = 20, effect_size = -5 )
n_units |
Number of units |
n_periods |
Number of time periods |
treatment_start |
When treatment begins |
effect_size |
Size of treatment effect |
A numeric matrix of dimension n_periods x n_units
(time in rows, units in columns); the first column is the treated unit.
sim <- generate_test_data(n_units = 10, n_periods = 30) dim(sim)sim <- generate_test_data(n_units = 10, n_periods = 30) dim(sim)
Generate all plots for SCM analysis
plot_all( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", treatment_label = "Treatment", show_ci = TRUE )plot_all( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", treatment_label = "Treatment", show_ci = TRUE )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
treatment_label |
Label for treatment (default "Treatment") |
show_ci |
Logical, whether to show confidence bands (default TRUE) |
Plot treatment effects only
plot_effects( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", show_ci = TRUE, show_vanilla = FALSE )plot_effects( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", show_ci = TRUE, show_vanilla = FALSE )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
show_ci |
Logical, whether to show confidence bands (default TRUE) |
show_vanilla |
Logical, whether to show vanilla SCM comparison (default FALSE) |
Plot method for scm_spillover objects
## S3 method for class 'scm_spillover' plot(x, type = "effects", ...)## S3 method for class 'scm_spillover' plot(x, type = "effects", ...)
x |
An object of class |
type |
Character; |
... |
Further arguments passed to |
A ggplot2 object (invisibly), as returned by the underlying plotting function.
Print method for scm_spillover objects
## S3 method for class 'scm_spillover' print(x, ...)## S3 method for class 'scm_spillover' print(x, ...)
x |
An object of class |
... |
Further arguments passed to or from other methods (unused). |
The input object x, invisibly.
Quick plot all three main plots in sequence
qplot_all( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", treatment_label = "Treatment", show_ci = TRUE, pause = TRUE )qplot_all( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", treatment_label = "Treatment", show_ci = TRUE, pause = TRUE )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
treatment_label |
Label for treatment (default "Treatment") |
show_ci |
Logical, whether to show confidence bands (default TRUE) |
pause |
Logical, whether to pause between plots (default TRUE) |
List of ggplot objects (invisibly)
Quick plot with confidence intervals only
qplot_ci( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome" )qplot_ci( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome" )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
ggplot object (invisibly)
Quick plot for method comparison (Spillover vs Vanilla)
qplot_compare( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome" )qplot_compare( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome" )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
ggplot object (invisibly)
Quick plot for treatment effects with confidence intervals
qplot_effects( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", show_ci = TRUE, show_vanilla = FALSE )qplot_effects( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", show_ci = TRUE, show_vanilla = FALSE )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
show_ci |
Logical, whether to show confidence bands (default TRUE) |
show_vanilla |
Logical, whether to show vanilla SCM comparison (default FALSE) |
ggplot object (invisibly)
Quick plot without confidence intervals
qplot_point( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome" )qplot_point( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome" )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
ggplot object (invisibly)
Quick plot for actual vs synthetic control time series
qplot_series( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", treatment_label = "Treatment" )qplot_series( result, start_year = NULL, unit_name = "Treated Unit", outcome_label = "Outcome", treatment_label = "Treatment" )
result |
Output from run_scm_spillover |
start_year |
First year of treatment period |
unit_name |
Name of treated unit (default "Treated Unit") |
outcome_label |
Label for outcome variable (default "Outcome") |
treatment_label |
Label for treatment (default "Treatment") |
ggplot object (invisibly)
Run Complete SCM Analysis with Spillover Effects
run_scm_spillover( data, treatment_start, treated_unit = 1, affected_units = NULL, verbose = TRUE )run_scm_spillover( data, treatment_start, treated_unit = 1, affected_units = NULL, verbose = TRUE )
data |
Matrix or data frame (time x units) |
treatment_start |
Integer, first treatment period (row number) |
treated_unit |
Integer, column index of treated unit (default = 1) |
affected_units |
Vector of column indices for all affected units (including treated) |
verbose |
Logical, print progress |
An object of class scm_spillover: a list with the
spillover-adjusted and standard treatment effects, confidence bounds,
the synthetic-control series, and the inputs used.
set.seed(1) sim <- generate_test_data(n_units = 10, n_periods = 30, treatment_start = 20) res <- run_scm_spillover(sim, treatment_start = 20, verbose = FALSE) res$spillover_effectsset.seed(1) sim <- generate_test_data(n_units = 10, n_periods = 30, treatment_start = 20) res <- run_scm_spillover(sim, treatment_start = 20, verbose = FALSE) res$spillover_effects
Safely inverts a matrix using regularization if needed
safe_solve(M, tol = 1e-10)safe_solve(M, tol = 1e-10)
M |
Matrix to invert |
tol |
Tolerance for condition number check |
Inverted matrix
Save all plots to files
save_all_plots( result, prefix = "scm", path = ".", width = 10, height = 6, dpi = 300, ... )save_all_plots( result, prefix = "scm", path = ".", width = 10, height = 6, dpi = 300, ... )
result |
Output from run_scm_spillover |
prefix |
File name prefix (default "scm") |
path |
Directory to save plots (default current directory) |
width |
Plot width in inches (default 10) |
height |
Plot height in inches (default 6) |
dpi |
Resolution (default 300) |
... |
Additional arguments passed to plotting functions |
Character vector of saved file names (invisibly)
Computes synthetic control weights for a single treated unit
scm(Y, lambda = 1e-06)scm(Y, lambda = 1e-06)
Y |
N x T matrix where first row is treated unit |
lambda |
Ridge regularization parameter for numerical stability |
List containing intercept (a) and weights (b)
set.seed(1) controls <- matrix(rnorm(5 * 20, 100, 10), nrow = 5) treated <- c(0.5, 0.3, 0.2, 0, 0) %*% controls + rnorm(20, 0, 0.5) Y <- rbind(treated, controls) fit <- scm(Y) fit$b # weights; first entry (0) is the treated unitset.seed(1) controls <- matrix(rnorm(5 * 20, 100, 10), nrow = 5) treated <- c(0.5, 0.3, 0.2, 0, 0) %*% controls + rnorm(20, 0, 0.5) Y <- rbind(treated, controls) fit <- scm(Y) fit$b # weights; first entry (0) is the treated unit
Computes synthetic control weights for all units
scm_batch(Y, verbose = FALSE)scm_batch(Y, verbose = FALSE)
Y |
N x T matrix of outcomes |
verbose |
Print progress messages |
List with intercepts (a) and weight matrix (B)
Tests whether spillover effects are significant
sp_andrews_spillover(Y0, Y1, A, alpha_sig = 0.05)sp_andrews_spillover(Y0, Y1, A, alpha_sig = 0.05)
Y0 |
N x T pre-treatment matrix |
Y1 |
N x 1 post-treatment vector |
A |
N x k spillover structure matrix |
alpha_sig |
Significance level |
List with test results
Tests significance of treatment effects
sp_andrews_te(Y0, Y1, A, C = NULL, alpha_sig = 0.05)sp_andrews_te(Y0, Y1, A, C = NULL, alpha_sig = 0.05)
Y0 |
N x T pre-treatment matrix |
Y1 |
N x 1 post-treatment vector (single period) |
A |
N x k spillover structure matrix |
C |
Constraint matrix (default tests first unit) |
alpha_sig |
Significance level |
List with estimates, p-values, and confidence intervals
Estimates treatment effects accounting for spillovers
sp_estimation(Y_pre, Y_post, A, verbose = FALSE)sp_estimation(Y_pre, Y_post, A, verbose = FALSE)
Y_pre |
N x T pre-treatment matrix |
Y_post |
N x S post-treatment matrix |
A |
N x k spillover structure matrix |
verbose |
Print progress messages |
List containing treatment effects and other results
Summary method for scm_spillover objects
## S3 method for class 'scm_spillover' summary(object, ...)## S3 method for class 'scm_spillover' summary(object, ...)
object |
An object of class |
... |
Further arguments passed to or from other methods (unused). |
A data frame of per-period effects, invisibly.
Computes standard synthetic control for comparison
vanilla_scm(Y_pre, Y_post)vanilla_scm(Y_pre, Y_post)
Y_pre |
N x T pre-treatment matrix |
Y_post |
N x S post-treatment matrix |
Synthetic control values for all periods