augsynth: Augmented Synthetic Control Method

repository·master·Indexed 41 days ago

https://github.com/ebenmichael/augsynth

An R package for estimating treatment effects in panel datasets using the Augmented Synthetic Control Method (ASCM). It provides three primary implementation types: single_augsynth for single treated units, multisynth for multiple treated units with staggered adoption, and augsynth_multiout for single treated units with multiple outcomes. The package supports ridge regression augmentation, auxiliary covariates, and various inference methods including wild bootstrap and conformal inference.

Tokens
3.6K
Snippets
14
Records
15
Agent score
50%

What's inside augsynth

  1. Overview of augsynth implementation types

    master

    The augsynth package implements the Augmented Synthetic Control Method (ASCM) through three distinct approaches depending on your experimental design:

    1. single_augsynth: Used for the classic synthetic control approach involving a single treated unit.
    2. multisynth: Used when estimating treatment effects for multiple treated units with staggered adoption.
    3. augsynth_multiout: Used for a single treated unit when there are multiple outcomes to analyze.
  2. Include auxiliary covariates in `multisynth()`

    master

    You can include additional covariates to balance simultaneously with the pre-treatment outcomes by adding them to the formula after a pipe (|) symbol.

    Usage:

    • Formula format: outcome ~ treatment | covariate1 + covariate2.
    • If covariates vary during pre-treatment periods, multisynth uses their average pre-treatment value by default.
    • Use the cov_agg argument to provide a custom aggregation function if the default average is not desired.

    Note: The auxiliary covariates must be present in the dataframe passed to multisynth().

    # Example: Including per capita income and student-teacher ratio as covariates
    ppool_syn_cov <- multisynth(lnppexpend ~ cbr | perinc_1959 + studteachratio_1959,
                                State, year, analysis_df_covs)
  3. Install augsynth from GitHub

    master

    To install the augsynth package, you need the devtools package. You can install devtools from CRAN and then use devtools::install_github() to pull the latest version of augsynth directly from the GitHub repository.

    # Install devtools if not already installed
    install.packages("devtools", repos='http://cran.us.r-project.org')
    # Install augsynth from github
    devtools::install_github("ebenmichael/augsynth")
  4. Prepare data for `multisynth`

    master

    To use the multisynth function for estimating treatment effects with staggered adoption, your dataset must include a treatment status column. This column should indicate whether a unit (e.g., a state) is treated in a specific year.

    In the provided example, a column cbr is created where a value of 1 indicates the unit is under treatment and 0 indicates it is not. Additionally, ensure that the year the treatment was adopted is represented (e.g., using Inf for units that are never treated) to facilitate logical comparisons.

    library(magrittr)
    library(dplyr)
    library(augsynth)
    
    # Example data preparation
    data %>%
        filter(!State %in% c("DC", "WI"),
               year >= 1959, year <= 1997) %>%
        mutate(YearCBrequired = ifelse(is.na(YearCBrequired), 
                                       Inf, YearCBrequired),
               cbr = 1 * (year >= YearCBrequired)) -> analysis_df
  5. Include auxiliary covariates in `augsynth`

    master

    You can include auxiliary covariates in the augmentation by adding them to the formula after a pipe |.

    • Aggregation: By default, time-invariant covariates are created by averaging the auxiliary covariates over the pre-intervention period (dropping NA values). Use cov_agg to specify a custom aggregation function.
    • Mechanism: The lagged outcomes and auxiliary covariates are jointly balanced by the SCM, and the ridge outcome model includes both.
    # Include covariates in the formula
    covsyn <- augsynth(lngdpcapita ~ treated | lngdpcapita + log(revstatecapita) + 
                                               log(revlocalcapita) + log(avgwklywagecapita) + 
                                               estabscapita + emplvlcapita,
                       fips, year_qtr, kansas,
                       progfunc = "ridge", scm = TRUE)
  6. Fit Augmented SCM on residuals

    master

    To fit ridge ASCM on the residuals of the initial model, use the residualize = TRUE argument. You can pass the lambda value from a previous augmentation to ensure consistency.

    # Fit on residuals using lambda from a previous model (asyn)
    covsyn_resid <- augsynth(lngdpcapita ~ treated | lngdpcapita + log(revstatecapita) + 
                                               log(revlocalcapita) + log(avgwklywagecapita) + 
                                               estabscapita + emplvlcapita,
                       fips, year_qtr, kansas,
                       progfunc = "ridge", scm = TRUE, 
                       lambda = asyn$lambda,
                       residualize = TRUE)
  7. Augment Synthetic Control with Ridge Regression

    master

    To reduce L2 imbalance, you can augment the synthetic control with an outcome model. Setting progfunc = "Ridge" fits a ridge regression model.

    • Hyperparameter Tuning: If lambda is not specified, it is determined via cross-validation.
    • Cross-Validation: You can visualize the cross-validation MSE by setting plot_type = "cv" in the plot() function.
    • CV Selection: By default, the procedure selects the maximal lambda with MSE within one standard deviation of the minimal MSE. To select the lambda that strictly minimizes the CV MSE, set min_1se = FALSE.
    # Augment with Ridge regression
    asyn <- augsynth(lngdpcapita ~ treated, fips, year_qtr, kansas,
                    progfunc = "Ridge", scm = TRUE)
    
    # Plot cross-validation MSE
    plot(asyn, plot_type = "cv")
  8. Basic usage of the augsynth function

    master

    To perform an Augmented Synthetic Control analysis, prepare a panel dataset containing the following variables:

    • outcome: The measure of interest.
    • trt: The treatment indicator.
    • unit: The unit indicator.
    • time: The time variable.
    • t_int: The intervention time.

    Use the augsynth function with a formula interface to estimate the effect.

    asyn <- augsynth(outcome ~ trt, unit, time, t_int, data)
  9. Summarize treatment effects with `summary()`

    master

    After fitting a model with multisynth(), use the summary() function to compute treatment effects (ATT), standard errors, and confidence intervals using the wild bootstrap.

    Arguments:

    • alpha: The significance level for confidence intervals (default is 0.05).

    Output:

    • The summary object contains global and individual L2 imbalance metrics.
    • The $att component is a dataframe containing point estimates, standard errors, and confidence limits.
    • In the att dataframe, Time = NA represents the effect averaged across all post-treatment periods.
    # Compute effects and confidence intervals
    ppool_syn_summ <- summary(ppool_syn)
    
    # Access the ATT dataframe
    att_data <- ppool_syn_summ$att
  10. Fit partially pooled synthetic controls with `multisynth()`

    master

    To estimate treatment effects with staggered adoption using partially pooled synthetic controls, use the multisynth() function.

    Arguments:

    • form: A formula of the form outcome ~ treatment.
    • unit: The variable identifying the unit (e.g., State).
    • time: The variable identifying the time period (e.g., year).
    • data: The dataframe containing the variables.
    • nu: The level of partial pooling.
      • nu = 0: Fits a separate synthetic control for each treated unit.
      • nu = 1: Fits fully pooled synthetic controls.
      • If omitted, multisynth uses a heuristic based on how well separate controls balance the overall average.
    • fixedeff: Boolean. By default, multisynth includes an intercept shift. Set fixedeff = FALSE to exclude it.
    • n_lags: Number of pre-treatment time periods to balance. Defaults to the number of pre-treatment periods for the last treated unit.
    • n_leads: Number of post-treatment time periods to estimate. Defaults to the number of post-treatment periods for the last treated unit.
    • time_cohort: Boolean. If TRUE, treated units with the same treatment time are collapsed into time cohorts, which can significantly speed up computation when treatment times are few.
    # Example: Fitting with a specific nu value
    ppool_syn <- multisynth(lnppexpend ~ cbr, State, year, 
                            nu = 0.5, analysis_df)
    
    # Example: Fitting with default nu
    ppool_syn <- multisynth(lnppexpend ~ cbr, State, year, 
                            analysis_df)
    
    # Example: Fitting with time cohorts enabled
    ppool_syn_time <- multisynth(lnppexpend ~ cbr, State, year,
                            analysis_df, time_cohort = TRUE)
  11. Run basic Synthetic Control Method with `augsynth()`

    master

    To find a synthetic control using only pre-intervention outcomes (without auxiliary covariates), use the augsynth() function. You must provide a formula in the form outcome ~ treatment, the unit identifier, the time variable, and the dataset. Setting progfunc = "None" and scm = TRUE performs a standard Synthetic Control Method (SCM) fit.

    Note: If t_int (intervention time) is not provided, the code will attempt to automatically determine it from the treatment column.

    library(augsynth)
    # Basic SCM fit
    syn <- augsynth(lngdpcapita ~ treated, fips, year_qtr, kansas,
                    progfunc = "None", scm = TRUE)