R/synthdid.R
synthdid_estimate.Rd
See 'Synthetic Difference in Differences' by Arkhangelsky et al. This implements Algorithm 1.
synthdid_estimate( Y, N0, T0, X = array(dim = c(dim(Y), 0)), noise.level = sd(apply(Y[1:N0, 1:T0], 1, diff)), eta.omega = ((nrow(Y) - N0) * (ncol(Y) - T0))^(1/4), eta.lambda = 1e-06, zeta.omega = eta.omega * noise.level, zeta.lambda = eta.lambda * noise.level, omega.intercept = TRUE, lambda.intercept = TRUE, weights = list(omega = NULL, lambda = NULL), update.omega = is.null(weights$omega), update.lambda = is.null(weights$lambda), min.decrease = 1e-05 * noise.level, max.iter = 10000, sparsify = sparsify_function, max.iter.pre.sparsify = 100 )
Y | the observation matrix. |
---|---|
N0 | the number of control units (N_co in the paper). Rows 1-N0 of Y correspond to the control units. |
T0 | the number of pre-treatment time steps (T_pre in the paper). Columns 1-T0 of Y correspond to pre-treatment time steps. |
X | an optional 3-D array of time-varying covariates. Shape should be N X T X C for C covariates. |
noise.level, | an estimate of the noise standard deviation sigma. Defaults to the standard deviation of first differences of Y. |
eta.omega | determines the tuning parameter zeta.omega = eta.omega * noise.level. Defaults to the value (N_tr T_post)^(1/4). |
eta.lambda | analogous for lambda. Defaults to an 'infinitesimal' value 1e-6. |
zeta.omega | if passed, overrides the default zeta.omega = eta.omega * noise.level. Deprecated. |
zeta.lambda | analogous for lambda. |
omega.intercept | Binary. Use an intercept when estimating omega. |
lambda.intercept | Binary. Use an intercept when estimating lambda. |
weights | a list with fields lambda and omega. If non-null weights$lambda is passed, we use them instead of estimating lambda weights. Same for weights$omega. |
update.omega | If true, solve for omega using the passed value of weights$omega only as an initialization. If false, use it exactly as passed. Defaults to false if a non-null value of weights$omega is passed. |
update.lambda | Analogous. |
min.decrease | Tunes a stopping criterion for our weight estimator. Stop after an iteration results in a decrease in penalized MSE smaller than min.decrease^2. |
max.iter | A fallback stopping criterion for our weight estimator. Stop after this number of iterations. |
sparsify | A function mapping a numeric vector to a (presumably sparser) numeric vector of the same shape, which must sum to one. If not null, we try to estimate sparse weights via a second round of Frank-Wolfe optimization initialized at sparsify( the solution to the first round ). |
max.iter.pre.sparsify | Analogous to max.iter, but for the pre-sparsification first-round of optimization. Not used if sparsify=NULL. |
An average treatment effect estimate with 'weights' and 'setup' attached as attributes. 'weights' contains the estimated weights lambda and omega and corresponding intercepts, as well as regression coefficients beta if X is passed. 'setup' is a list describing the problem passed in: Y, N0, T0, X.