The sccic package implements the Changes-in-Changes (CIC) estimator of Athey and Imbens (2006), combined with synthetic control methods for causal inference. It provides two main functions:
cic(): Standard CIC for two-group, two-period
settingssc_cic(): Synthetic control + CIC for
single-treated-unit settingsWe demonstrate cic() on the workers’ compensation data
from Meyer, Viscusi, and Durbin (1995), the dataset used in the
supplementary application of Athey and Imbens (2006). Injury duration is
measured in integer weeks, so both the continuous estimator (the
default) and the discrete estimator (discrete = TRUE) are
relevant.
library(sccic)
# Load workers' comp data
if (requireNamespace("wooldridge", quietly = TRUE)) {
data("injury", package = "wooldridge")
y_00 <- injury$ldurat[injury$highearn == 0 & injury$afchnge == 0]
y_01 <- injury$ldurat[injury$highearn == 0 & injury$afchnge == 1]
y_10 <- injury$ldurat[injury$highearn == 1 & injury$afchnge == 0]
y_11 <- injury$ldurat[injury$highearn == 1 & injury$afchnge == 1]
# Continuous CIC (Theorem 3.1)
result <- cic(y_00, y_01, y_10, y_11)
print(result)
# Discrete CIC (Theorem 4.1) — matches Athey and Imbens (2006)
result_d <- cic(y_00, y_01, y_10, y_11, discrete = TRUE, boot = FALSE)
print(result_d)
}
#>
#> Changes-in-Changes Estimator
#> ----------------------------------------
#> Estimator: continuous (Theorem 3.1)
#> tau^CIC = 0.0687
#> tau^DID = 0.1883
#> SE = 0.4044
#> z-stat = 0.1699
#> p-value = 0.8651
#> N = 7150 (2294/2004/1472/1380)
#> Analytic standard errors (Theorem 5.1) assume a continuous outcome distribution and are not valid when discrete = TRUE. Use boot = TRUE for inference.
#>
#> Changes-in-Changes Estimator
#> ----------------------------------------
#> Estimator: discrete (Theorem 4.1)
#> tau^CIC = 0.1842
#> tau^DID = 0.1883
#> N = 7150 (2294/2004/1472/1380)C:14bb47d8d33a8-intro.R
The discrete CIC estimate (0.184) closely matches the value reported by Athey and Imbens (2006) (0.18 on a subsample of N = 5,624), confirming the correctness of the implementation. The continuous CIC estimate (0.069) treats log-transformed duration as approximately continuous.
For settings with a single treated unit and multiple donors,
sc_cic() combines synthetic control construction with CIC
estimation. We demonstrate on the Basque Country terrorism dataset.
if (requireNamespace("Synth", quietly = TRUE)) {
data("basque", package = "Synth")
# Reshape to wide format
gdp <- reshape(basque[, c("regionno", "year", "gdpcap")],
idvar = "year", timevar = "regionno", direction = "wide")
y_treated <- gdp[, "gdpcap.17"] # Basque Country
donor_cols <- grep("gdpcap\\.", names(gdp), value = TRUE)
donor_cols <- donor_cols[!donor_cols %in% c("gdpcap.17", "gdpcap.1")]
donors <- as.matrix(gdp[, donor_cols])
valid <- complete.cases(y_treated, donors)
result2 <- sc_cic(y_treated[valid], donors[valid, ],
treatment_period = 16, seed = 42)
print(result2)
}
#>
#> Synthetic Control + Changes-in-Changes Estimator
#> --------------------------------------------------
#> SC donors selected: 4
#> Pre-treatment RMSE: 0.0493
#> Pre-treatment KS p: 0.938 [OK]
#> --------------------------------------------------
#> tau^CIC = -0.7943
#> tau^DID = -0.7346
#> boot SE = 0.3229
#> z-stat = -2.4596
#> p-value = 0.01391
#> N = 86 (15/28/15/28)C:14bb47d8d33a8-intro.R
Both functions support bootstrap inference via the boot
argument:
C:14bb47d8d33a8-intro.R