install.packages("MSCMT")
install.packages("Synth")
::install_github("ebenmichael/augsynth") devtools
Compare Synthetic Control methods which allows multiple outcomes
library(MSCMT)
library(Synth)
library(augsynth)
library(multisynthdid)
library(tidyverse)
data("german_reunification")
$index <- as.integer(as.factor(german_reunification$country) )
german_reunification<- as.data.frame(german_reunification) german_reunification
Classical Synthetic Control
<- unique(german_reunification$index)[-7]
unit_ids <-
dataprep_out dataprep(
foo = german_reunification,
predictors = c("gdp","trade","infrate"),
dependent = "gdp",
unit.variable = "index",
time.variable = "year",
treatment.identifier = 17,
controls.identifier = unit_ids[unit_ids != 17],
time.predictors.prior = 1981:1990,
time.optimize.ssr = 1960:1989,
unit.names.variable = "country",
time.plot = 1960:2003
)
<- synth(dataprep_out) synth_out
X1, X0, Z1, Z0 all come directly from dataprep object.
****************
searching for synthetic control unit
****************
****************
****************
MSPE (LOSS V): 25490.84
solution.v:
0.8782577 0.1213023 0.0004399473
solution.w:
0.009213684 0.03014281 0.01528837 0.01577015 0.01249197 0.007024813 0.009557229 0.3023965 0.1640184 0.009600453 0.01275447 0.007048682 0.008689053 0.2884409 0.01233855 0.095224
MSCMT package
<- listFromLong(german_reunification, unit.variable="index", time.variable="year", unit.names.variable="country")
df_m
# define the sum of all cases
<- "West Germany"
treatment.identifier <- setdiff(colnames(df_m[[1]]),
controls.identifier c(treatment.identifier))
<- cbind("gdp" = c(1960,1989),
times.dep "trade" = c(1960,1989),
"infrate" = c(1960,1989))
<- times.dep
times.pred
<- mscmt(df_m, treatment.identifier, controls.identifier, times.dep, times.pred, seed=1) mscmt_res
14:27:55: Number of 'sunny' donors: 16 out of 16
14:27:55: Unrestricted outer optimum (obtained by ignoring all predictors) is
14:27:55: FEASIBLE even when respecting the predictors.
Final rmspe: 0.03346181, mspe (loss v): 0.001119693
Optimal weights:
USA Austria Switzerland Japan
0.26457047 0.49918982 0.17248101 0.06375869
Augmented Synthetic Control
<- augsynth( gdp + trade + infrate ~ W, index, year,
aug_syn progfunc = 'none', scm = T ) german_reunification,
Multiple outcomes and one treatment time found. Running augsynth_multiout.
summary(aug_syn)
Call:
augsynth_multiout(form = form, unit = !!enquo(unit), time = !!enquo(time),
t_int = t_int, data = data, progfunc = "none", scm = ..2)
Overall L2 Imbalance (Scaled):0.450 (0.296)
Average ATT Estimate:
Outcome Estimate lower_bound upper_bound p_val Pre.RMSE
1 gdp -2360.7643331 NA NA 0 310.710322
2 trade 8.0726848 NA NA 0 7.290110
3 infrate -0.4014653 NA NA 0 1.930879
# Treatment
= predict(aug_syn,att=T) augsyn_tau
<- multi_sdid( gdp + infrate + trade ~ 1, 'W', 'country', 'year', german_reunification )
multi_sdid
summary.multisynthdid(multi_sdid)
$estimate
[1] "multi_synthdid_obj"
$tau
gdp infrate trade
Avg. Treatment -1526.459 1.397776 0.3985817
SE 1340.875 1.588531 4.2371690
$dimensions
[,1]
No. Treated units 1.000
No. Control pool 16.000
Effective no. controls 8.668
No. Post-treatment periods 14.000
No. Pre-treatment periods 30.000
Effective no. pre-treatment periods 1.000
No. Outcomes 3.000
<- multi_synthdid_curves(multi_sdid$tau, complete = T) msdid_curve
Comparison of GDP
<- german_reunification %>%
df_plot filter( country == 'West Germany' ) %>%
arrange( year ) %>%
rename( `Realized GDP` = gdp )
<- cbind(df_plot,
df_plot tibble(SC = dataprep_out$Y0plot %*% synth_out$solution.w ),
tibble(MSCMT = as.vector( mscmt_res$data.synth$gdp) ),
tibble(Aug_Synth = df_plot$`Realized GDP`-augsyn_tau[,1] ),
tibble(Multi_SDiD = df_plot$`Realized GDP` - msdid_curve$tau_curve[1,]) )
<- df_plot %>%
df_plot2 select( year, `Realized GDP`, SC, MSCMT, Aug_Synth, Multi_SDiD ) %>% #
pivot_longer(!year, names_to = 'Method', values_to = 'GDP' )
ggplot( df_plot2, aes( x = year, color = Method, y = GDP )) +
geom_line( linewidth = 1 ) +
annotate("rect", xmin = 1960, xmax = 1990, ymin = 0, ymax = 35000,
alpha = .2)+
theme_bw()