Skip to contents

Returns the tidy data.frame that plot() draws for a given type, so the underlying series, weights, or placebo paths can be inspected, joined into a table, or re-plotted directly. plot() stays the quick path; plot_data() is the handle for anyone who wants to relabel simplified series names, feed the numbers into their own figure, or postprocess them further.

Usage

plot_data(x, ...)

# Default S3 method
plot_data(x, ...)

# S3 method for class 'coresynth'
plot_data(
  x,
  type = c("trend", "gap", "weights", "pred_weights"),
  align = FALSE,
  top_n = Inf,
  show_donors = 0,
  ...
)

# S3 method for class 'scm_placebo'
plot_data(x, type = c("gaps", "ratios"), mspe_prune = Inf, ...)

Arguments

x

A coresynth fit (from scm_fit()) or a scm_placebo object (from mspe_ratio_pval()).

...

Passed to methods (unused by the current methods).

type

For a coresynth fit: one of "trend", "gap", "weights", or "pred_weights", matching plot.coresynth(). For a scm_placebo object: "gaps" or "ratios", matching plot.scm_placebo().

align

For type = "trend"/"gap": when TRUE, shift the synthetic series by its pre-treatment level gap to the treated series, exactly as in plot.coresynth(). Default FALSE (raw series).

top_n

For type = "weights"/"pred_weights": keep only the top_n largest weights (default Inf, every row).

show_donors

For type = "trend": also return the outcome paths of the show_donors largest-weight donors as series = "Donors" rows, adding a unit column that identifies each donor (NA for the treated and synthetic series). Default 0 (treated and synthetic series only).

mspe_prune

For a scm_placebo object with type = "gaps": drop placebo units whose pre-treatment MSPE exceeds mspe_prune times the treated unit's, as in plot.scm_placebo(). Default Inf (no pruning).

Value

A tidy data.frame. Columns by type:

"trend"

time, value, series ("Treated" / "Synthetic Control"); with show_donors > 0, also "Donors" rows and a unit column.

"gap"

time, gap (treated minus synthetic control).

"weights"

unit, weight; SDID fits add a panel column ("omega" unit weights, "lambda" time weights), with unit holding the pre-period label for "lambda" rows.

"pred_weights"

predictor, weight (sharp SCM only).

"gaps"

time, gap, unit (NA for the treated series), series ("Treated" / "Placebo (donor pool)").

"ratios"

unit, ratio, series.

Details

The frame mirrors what the matching plot(x, type = ...) call shows, with two deliberate departures that make it a better data source:

  • Plain column names (time, value, series, weight, ...) are used instead of the dotted convention of augment(), since this is data to manipulate rather than model-augmented observations.

  • The cosmetic "drop donors with weight below 1e-4" filter that plot(type = "weights") applies is not used here: every donor is returned (use top_n to subset), so the frame is the complete set of weights.

Only the arguments that change which rows or values appear are accepted (align, top_n, show_donors, mspe_prune); purely cosmetic arguments of plot() (colors, labels, vline, fill, ...) have no data counterpart and are not part of this interface.

Examples

set.seed(1)
panel <- expand.grid(unit = 1:10, year = 1:20)
panel$treated <- as.integer(panel$unit == 5 & panel$year > 15)
panel$gdp <- panel$unit + 0.5 * panel$year +
  rnorm(nrow(panel)) + 3 * panel$treated
fit <- scm_fit(gdp ~ treated | unit + year, data = panel, method = "scm")
#> predictors = NULL: using the outcome in each of the 15 pre-treatment periods as predictors (outcomes-only SCM).

head(plot_data(fit, type = "trend"))
#>   time    value  series
#> 1    1 5.829508 Treated
#> 2    2 7.124931 Treated
#> 3    3 7.119826 Treated
#> 4    4 5.622940 Treated
#> 5    5 6.811244 Treated
#> 6    6 9.433024 Treated
plot_data(fit, type = "gap")
#>    time        gap
#> 1     1  0.6891996
#> 2     2  1.1156826
#> 3     3  0.6389665
#> 4     4 -1.4102499
#> 5     5 -0.3981566
#> 6     6  1.0250817
#> 7     7 -0.8091701
#> 8     8 -1.1200032
#> 9     9  0.3575763
#> 10   10  1.2546665
#> 11   11 -0.9000286
#> 12   12 -0.2251536
#> 13   13 -0.3513749
#> 14   14  1.0775897
#> 15   15 -0.4918579
#> 16   16  2.3230505
#> 17   17  1.8081601
#> 18   18  2.4650018
#> 19   19  3.4618267
#> 20   20  2.1599383
plot_data(fit, type = "weights")
#>   unit      weight
#> 1    1 0.000000000
#> 2    2 0.295837208
#> 3    3 0.208480416
#> 4    4 0.000000000
#> 5    6 0.272073605
#> 6    7 0.003527357
#> 7    8 0.000000000
#> 8    9 0.220081414
#> 9   10 0.000000000

# Relabel the simplified series names, then plot it yourself
df <- plot_data(fit, type = "trend")
df$series <- sub("Synthetic Control", "Synthetic Unit 5", df$series)
# \donttest{
ggplot2::ggplot(df, ggplot2::aes(time, value, color = series)) +
  ggplot2::geom_line()

# }