| Type: | Package |
| Title: | Fixed Effects Counterfactual Estimators |
| Version: | 2.4.1 |
| Date: | 2026-04-29 |
| Author: | Licheng Liu [aut], Ziyi Liu [aut], Ye Wang [aut], Yiqing Xu [aut, cre], Tianzhu Qin [aut], Shiyun Hu [aut], Rivka Lipkovitz [aut] |
| Maintainer: | Yiqing Xu <yiqingxu@stanford.edu> |
| Description: | Provides tools for estimating causal effects in panel data using counterfactual methods, as well as other modern DID estimators. It is designed for causal panel analysis with binary treatments under the parallel trends assumption. The package supports scenarios where treatments can switch on and off and allows for limited carryover effects. It includes several imputation estimators, such as Gsynth (Xu 2017), linear factor models, and the matrix completion method. Detailed methodology is described in Liu, Wang, and Xu (2024) <doi:10.48550/arXiv.2107.00856> and Chiu et al. (2025) <doi:10.48550/arXiv.2309.15983>. Optionally integrates with the "HonestDiDFEct" package for sensitivity analyses compatible with imputation estimators. "HonestDiDFEct" is not on CRAN but can be obtained from https://github.com/lzy318/HonestDiDFEct. |
| URL: | https://yiqingxu.org/packages/fect/, https://github.com/xuyiqing/fect |
| BugReports: | https://github.com/xuyiqing/fect/issues |
| NeedsCompilation: | yes |
| License: | MIT + file LICENSE |
| Imports: | Rcpp (≥ 0.12.3), ggplot2 (≥ 2.1.0), GGally (≥ 1.0.1), doParallel (≥ 1.0.10), doFuture, foreach (≥ 1.4.3), abind (≥ 1.4-0), codetools, MASS, gridExtra, grid, fixest, doRNG, future, parallelly, mvtnorm, dplyr, future.apply, reshape2, rlang, scales, splines |
| Suggests: | panelView, testthat (≥ 3.0.0), did, DIDmultiplegtDYN, ggrepel, HonestDiDFEct |
| Depends: | R (≥ 4.1.0) |
| LinkingTo: | Rcpp, RcppArmadillo |
| RoxygenNote: | 7.3.3 |
| Packaged: | 2026-04-29 21:35:21 UTC; yiqingxu |
| Encoding: | UTF-8 |
| Config/testthat/edition: | 3 |
| LazyData: | true |
| Repository: | CRAN |
| Date/Publication: | 2026-04-30 08:50:03 UTC |
Fixed Effects Counterfactual Estimators
Description
The fect package implements counterfactual estimators for Time-Series Cross-Sectional (TSCS) data analysis, along with statistical tools to test their identification assumptions.
Details
The fect package provides tools for estimating treatment effects in TSCS datasets using a range of counterfactual estimators. These estimators first impute counterfactuals for treated observations by fitting an outcome model (fixed effects model, interactive fixed effects model, or matrix completion) to untreated observations. Then, the individual treatment effect for each treated observation is calculated as the difference between the observed and predicted counterfactual outcomes.
The package supports:
Calculation of the Average Treatment Effect on the Treated (ATT) and period-specific ATTs.
Placebo tests and equivalence tests to evaluate the validity of the identification assumptions.
Robust estimation techniques for unbalanced panel datasets.
See fect for details.
Author(s)
Licheng Liu (liulch@mit.edu), Massachusetts Institute of Technology
Ye Wang (yw1576@nyu.edu), New York University
Yiqing Xu (yiqingxu@stanford.edu), Stanford University
Ziyi Liu (zyliu2020@uchicago.edu), University of Chicago
References
Athey, S., Bayati, M., Doudchenko, N., Imbens, G., and Khosravi, K. (2021). Matrix completion methods for causal panel data models. Journal of the American Statistical Association, 116(536), 1716-1730.
Bai, J. (2009). Panel data models with interactive fixed effects. Econometrica, 77(4), 1229-1279.
Liu, L., Wang, Y., and Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160-176.
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.
Calculate Cumulative Treatment Effects
Description
Calculate cumulative treatment effects based on the results of a fect object.
Usage
att.cumu(x, period = NULL, weighted = TRUE, alpha = 0.05, type = "on", plot = FALSE)
Arguments
x |
A |
period |
A two-element numeric vector specifying the range of terms during which treatment effects are to be accumulated, e.g., |
weighted |
A logical flag specifying whether to calculate weighted cumulative treatment effects based on counts at each period. Default is |
alpha |
A numerical value specifying the significance level. Default is |
type |
A string that specifies the type of effect to calculate. Must be one of the following: |
plot |
A logical flag indicating whether to plot cumulative effects. Default is |
Author(s)
Licheng Liu, Ye Wang, and Yiqing Xu
References
Athey, S., Bayati, M., Doudchenko, N., Imbens, G., and Khosravi, K. (2021). Matrix completion methods for causal panel data models. Journal of the American Statistical Association, 116(536), 1716-1730.
Bai, J. (2009). Panel data models with interactive fixed effects. Econometrica, 77(4), 1229-1279.
Liu, L., Wang, Y., and Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160-176.
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.
See Also
A Multi-Method Difference-in-Differences Estimator
Description
Implements multiple difference-in-differences (DiD) estimators under a unified interface, supporting overall ATT and event-study estimates across staggered adoption settings.
Usage
did_wrapper(
data,
Y,
D,
X = NULL,
index,
method = c("twfe", "st", "iw", "cs_never", "cs_notyet", "didm"),
se = c("default", "boot", "bootstrap", "jackknife"),
nboots = 200,
parallel = TRUE,
core = NULL,
time_to_treat_var = "Time_to_Treatment",
treat_indicator = "treat",
csdid.base_period = "universal",
didm.effects = NA,
didm.placebo = NA
)
Arguments
data |
Input data frame. |
Y |
Outcome variable name (string). |
D |
Treatment indicator variable name (string). |
X |
Optional covariate vector for adjustment. |
index |
Character vector of unit and time variable names, e.g., |
method |
DiD method: |
se |
Standard error method: |
nboots |
Number of bootstrap replications (if applicable). |
parallel |
Logical; use parallel computation for bootstrapping. |
core |
Number of CPU cores to use if |
time_to_treat_var |
Name of time-to-treatment variable; used internally. |
treat_indicator |
Name of treatment cohort indicator variable; used internally. |
csdid.base_period |
Baseline period choice for Callaway–Sant'Anna estimators. |
didm.effects |
Effects vector for |
didm.placebo |
Placebo vector for |
Details
This function:
Drops always-treated units.
Constructs event time and cohort variables.
Computes ATT using the specified DiD method.
Constructs event-study ATT curves.
Optionally estimates bootstrap or jackknife standard errors.
Supported methods include TWFE, stacked DiD, interaction-weighted DiD, Callaway–Sant'Anna estimators, placebo DiD, and DIDmultiplegt.
Value
A list of class "did_wrapper":
est.avg |
Data frame with overall ATT, standard error, confidence interval, and p-value. |
est.att |
Event-study ATT estimates by relative period, including standard errors and confidence intervals. |
Author(s)
Rivka Lipkovitz
Examples
## Not run:
result_twfe <- did_wrapper(
data = df,
Y = "outcome",
D = "treat",
index = c("id", "time"),
method = "twfe"
)
result_twfe$est.avg
result_twfe$est.att
## End(Not run)
Calculate Cumulative or Sub-group Treatment Effects
Description
Calculates cumulative or average treatment effects for specified units and time periods based on a fitted fect object. The function supports both cumulative effects over time and period-specific average treatment effects, with bootstrap-based uncertainty estimates.
Usage
effect(
x,
cumu = TRUE,
id = NULL,
period = NULL,
plot = FALSE,
count = TRUE,
xlab = NULL,
ylab = NULL,
main = NULL
)
Arguments
x |
A |
cumu |
Logical. If |
id |
Character vector or NULL. Unit identifiers to include in the analysis. If |
period |
Numeric vector of length 2 specifying the time window |
plot |
Logical. If |
count |
Logical. If |
xlab |
Character. X-axis label for the plot. |
ylab |
Character. Y-axis label for the plot. |
main |
Character. Main title for the plot. |
Details
The function processes treatment effects in several steps:
1. Selects units based on the id parameter or includes all treated units if id = NULL.
2. Calculates relative time to treatment for each unit.
3. If cumu = TRUE, computes cumulative effects by summing average effects up to each period.
4. Performs bootstrap analysis to estimate uncertainty (standard errors, confidence intervals, and p-values).
The function supports different inference methods (bootstrap, jackknife, parametric) and adjusts calculations accordingly.
Note: The function requires bootstrap results in the input fect object (keep.sims = TRUE must be set when fitting the model).
Value
Returns a list containing:
eff |
Vector of point estimates for cumulative or average treatment effects. |
est.eff |
Matrix containing the following columns:
|
Warning
The function will stop with an error if:
No bootstrap results are available in the input object
The panel contains treatment reversals
The specified ending period exceeds the maximum available period
Author(s)
Shiyun Hu, Licheng Liu, Ye Wang, and Yiqing Xu
References
Liu, L., Wang, Y., & Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160-176.
See Also
Examples
## Not run:
# Fit fect model with bootstrap
fit <- fect(Y ~ D + X, data = panel_data, keep.sims = TRUE)
# Calculate cumulative effects for all treated units
results <- effect(fit)
# Calculate period-specific effects for specific units
results_specific <- effect(fit,
cumu = FALSE,
id = c("unit1", "unit2"),
period = c(1, 4))
# View results
print(results$est.catt)
## End(Not run)
Event Study Visualization
Description
Visualize dynamic treatment effects and create an event study plot. This function offers flexibility in displaying estimates, confidence intervals, and various annotations. It can handle data directly or from 'did_wrapper' objects, calculate confidence intervals from standard errors if needed, and allows for connected (line/ribbon) or point-range style plots.
Usage
esplot(data, Period = NULL, Estimate = "ATT", SE = NULL,
CI.lower = "CI.lower", CI.upper = "CI.upper", Count = NULL,
proportion = 0.3, est.lwidth = NULL, est.pointsize = NULL,
show.points = TRUE, fill.gap = TRUE, start0 = FALSE,
only.pre = FALSE, only.post = FALSE, show.count = TRUE,
stats = NULL, stats.labs = NULL, highlight.periods = NULL,
highlight.colors = NULL, highlight.shapes = NULL,
highlight.fill = FALSE,
lcolor = NULL, lwidth = NULL,
ltype = NULL, connected = FALSE, ci.outline = FALSE,
main = NULL, xlim = NULL, ylim = NULL, xlab = NULL, ylab = NULL,
gridOff = FALSE, stats.pos = NULL, theme.bw = TRUE,
legacy.style = FALSE,
cex.main = NULL, cex.axis = NULL, cex.lab = NULL,
cex.text = NULL, axis.adjust = FALSE, color = "#000000",
pre.color = NULL, post.color = NULL,
count.color = "gray70", count.alpha = 0.4,
count.outline.color = "grey69",
xangle = NULL, yangle = NULL,
xbreaks = NULL, ybreaks = NULL,
legendOff = FALSE, cex.legend = NULL,
pre.label = "Pre-treatment", post.label = "Post-treatment")
Arguments
data |
The input data for the event study plot. Can be a |
Period |
The name of the column in |
Estimate |
The name of the column in |
SE |
The name of the column in |
CI.lower |
The name of the column in |
CI.upper |
The name of the column in |
Count |
Optional. The name of the column in |
proportion |
Numeric, between 0 and 1. If |
est.lwidth |
Numeric. The line width for the estimate line (if |
est.pointsize |
Numeric. The size of the points. If |
show.points |
Logical. If |
fill.gap |
Logical. If |
start0 |
Logical. If |
only.pre |
Logical. If |
only.post |
Logical. If |
show.count |
Logical. Whether to display a bar plot of the values from the |
stats |
Optional. A numeric vector of statistics (e.g., p-values) to be printed on the plot. |
stats.labs |
Optional. A character vector of labels corresponding to the |
highlight.periods |
Optional. A numeric vector of time periods to highlight with different colors. For |
highlight.colors |
Optional. A character vector of colors corresponding to |
highlight.shapes |
Optional. An integer vector of point shapes corresponding to |
highlight.fill |
Logical. If |
lcolor |
Optional. Color(s) for the reference lines. Can be a single color (applied to both horizontal y=0 line and vertical pre/post separator line) or a vector of two colors (first for horizontal, second for vertical). If |
lwidth |
Optional. Line width(s) for the reference lines. Can be a single width or a vector of two widths (similar to |
ltype |
Optional. Linetype(s) for the reference lines. Can be a single linetype (applied to both horizontal y=0 line and vertical pre/post separator line) or a vector of two linetypes (first for horizontal, second for vertical). Default is |
connected |
Logical. If |
ci.outline |
Logical. If |
main |
Optional. The main title for the plot. If |
xlim |
Optional. A numeric vector of length 2 specifying the x-axis limits ( |
ylim |
Optional. A numeric vector of length 2 specifying the y-axis limits ( |
xlab |
Optional. The label for the x-axis. If |
ylab |
Optional. The label for the y-axis. If |
gridOff |
Logical. Whether to turn off major and minor grid lines. Default is |
stats.pos |
Optional. A numeric vector of length 2 ( |
theme.bw |
Logical. Whether to use |
legacy.style |
Logical. If |
cex.main |
Optional. Numeric scaling factor for the plot title font size. The base size used by ggplot is 16. Default is |
cex.axis |
Optional. Numeric scaling factor for the axis tick mark labels font size. The base size used by ggplot is 15. Default is |
cex.lab |
Optional. Numeric scaling factor for the axis title (x and y labels) font size. The base size used by ggplot is 15. Default is |
cex.text |
Optional. Numeric scaling factor for annotated text elements (e.g., |
axis.adjust |
Logical. If |
color |
Character. The primary color for plotting estimates, points, lines, and confidence interval fills/lines (unless overridden by |
pre.color |
Optional. Character. Color for pre-treatment period estimates. If |
post.color |
Optional. Character. Color for post-treatment period estimates. If |
count.color |
Character. The fill color for the bars if |
count.alpha |
Numeric. Alpha transparency for the count bars if |
count.outline.color |
Character. The color for the outline of count bars if |
xangle |
Optional. Numeric. Rotation angle (in degrees) for x-axis tick labels. Default is |
yangle |
Optional. Numeric. Rotation angle (in degrees) for y-axis tick labels. Default is |
xbreaks |
Optional. A numeric vector of break points for the x-axis. If |
ybreaks |
Optional. A numeric vector of break points for the y-axis. If |
legendOff |
Logical. If |
cex.legend |
Optional. Numeric scaling factor for the legend text size. Default is |
pre.label |
Character. Label for the pre-treatment period in the legend. Default is |
post.label |
Character. Label for the post-treatment period in the legend. Default is |
Value
p |
A |
Author(s)
Licheng Liu, Yiqing Xu, Ziyi Liu, Zhongyu Yin, Rivka Lipkovitz
Examples
# Basic example with simulated data
set.seed(123)
event_data <- data.frame(
time = -5:5,
ATT = cumsum(rnorm(11, 0, 0.2)) + c(rep(0,5), 0, 0.5, 1, 1.2, 1.5, 1.3),
SE = runif(11, 0.1, 0.3)
)
event_data$CI.lower <- event_data$ATT - 1.96 * event_data$SE
event_data$CI.upper <- event_data$ATT + 1.96 * event_data$SE
event_data$count <- sample(50:150, 11, replace = TRUE)
event_data$count[event_data$time == -5 | event_data$time == 5] <- 20 # for proportion demo
# Default plot (point-range)
esplot(event_data, Period = "time", Estimate = "ATT",
CI.lower = "CI.lower", CI.upper = "CI.upper")
# # Connected plot with ribbon
# esplot(event_data, Period = "time", Estimate = "ATT",
# CI.lower = "CI.lower", CI.upper = "CI.upper",
# connected = TRUE, show.points = TRUE)
# # Connected plot using SE for CI calculation
# event_data_no_ci <- event_data[, c("time", "ATT", "SE", "count")]
# esplot(event_data_no_ci, Period = "time", Estimate = "ATT", SE = "SE",
# connected = TRUE, ci.outline = TRUE, color = "blue")
# # Show count bars and stats
# esplot(event_data, Period = "time", Estimate = "ATT",
# CI.lower = "CI.lower", CI.upper = "CI.upper", Count = "count",
# show.count = TRUE, stats = c(0.03, 0.12), stats.labs = c("P-val Pre", "P-val Post"),
# main = "Event Study with Counts and Stats", proportion = 0.2)
# # Highlight specific periods (connected)
# esplot(event_data, Period = "time", Estimate = "ATT", SE = "SE",
# connected = TRUE, highlight.periods = c(-1, 2),
# highlight.colors = c("orange", "green"),
# main = "Highlighted Periods (Connected)")
# # Highlight specific periods (point-range)
# esplot(event_data, Period = "time", Estimate = "ATT", SE = "SE",
# connected = FALSE, highlight.periods = c(-1, 2),
# highlight.colors = c("orange", "green"),
# main = "Highlighted Periods (Point-Range)")
# # Only post-treatment period, custom labels
# esplot(event_data, Period = "time", Estimate = "ATT", SE = "SE",
# only.post = TRUE, xlab = "Years Post-Intervention", ylab = "Impact Metric",
# start0 = TRUE, color = "darkred", est.lwidth = 1.5)
# Using did_wrapper object (conceptual example, requires `did` package and setup)
# if (requireNamespace("did", quietly = TRUE)) {
# # Assume `did_out` is an output from `did::att_gt` or similar
# # and `did_wrapper_obj` is created, e.g.,
# # did_wrapper_obj <- list(est.att = event_data) # Simplified for example
# # class(did_wrapper_obj) <- "did_wrapper"
# # esplot(did_wrapper_obj) # Would use defaults: Period="time", Estimate="ATT"
# }
Post-hoc Estimand Dispatcher
Description
Computes a post-hoc estimand from a fect fit, with bootstrap or
jackknife uncertainty. The type argument selects from a closed
enum of mathematically-defined estimands; the by argument
selects the grouping axis. The accessor imputed_outcomes
is the underlying long-form data source for any estimand the
dispatcher does not ship natively.
Usage
estimand(
fit,
type = c("att", "att.cumu", "aptt", "log.att"),
by = c("event.time", "cohort", "calendar.time", "overall"),
cells = NULL,
weights = NULL,
window = NULL,
direction = c("on", "off"),
vartype = c("bootstrap", "jackknife", "parametric", "none"),
conf.level = 0.95,
ci.method = c("basic", "percentile")
)
Arguments
fit |
A |
type |
Estimand type. |
by |
Grouping axis. One of |
cells |
Optional filter on which treated cells to include.
Accepts |
weights |
Aggregation-weight handling. |
window |
Optional event-time window |
direction |
Either |
vartype |
|
conf.level |
Two-sided confidence level. Defaults to 0.95. |
ci.method |
|
Value
A data frame with columns <by_key>, estimate, se,
ci.lo, ci.hi, n_cells, and vartype.
Always tidy regardless of type or by.
Numerical equality with existing slots
estimand(fit, "att", "event.time") returns estimate,
se, ci.lo, ci.hi byte-identical to columns
ATT, S.E., CI.lower, CI.upper of
fit$est.att, when default arguments are used. This invariant
is asserted by package tests.
References
Chen, Jiafeng, and Jonathan Roth. 2024. "Logs with Zeros? Some Problems and Solutions." Quarterly Journal of Economics 139 (2): 891–936.
See Also
imputed_outcomes for the underlying long-form accessor;
fect for the fitting interface.
Examples
## Not run:
library(fect)
fit <- fect(Y ~ D, data = simdata, index = c("id", "time"),
method = "fe", force = "two-way",
se = TRUE, nboots = 200, parallel = FALSE)
## Default: per-event-time ATT (matches fit$est.att numerically).
est <- estimand(fit, "att", "event.time")
head(est)
## End(Not run)
Fixed Effects Counterfactual Estimators
Description
Implements counterfactual estimators in TSCS data analysis and statistical tools to test their identification assumptions.
Usage
fect(formula = NULL, data, Y, D, X = NULL,
W = NULL, W.est = NULL, W.agg = NULL,
group = NULL,
na.rm = FALSE,
index, force = "two-way",
time.component.from = "notyettreated", em = TRUE,
r = 0, lambda = NULL, nlambda = 10,
CV = NULL, k = 20, cv.prop = 0.1, cv.method = "rolling",
cv.nobs = 3, cv.donut = 1, cv.buffer = 1, criterion = "mspe",
binary = FALSE, QR = FALSE,
method = "fe", se = FALSE, vartype = "bootstrap", cl = NULL,
quantile.CI = FALSE, nboots = 200, alpha = 0.05,
parallel = TRUE, cores = NULL, tol = 1e-3,
max.iteration = 1000, seed = NULL,
min.T0 = NULL, max.missing = NULL,
proportion = 0.3, pre.periods = NULL,
f.threshold = 0.5, tost.threshold = NULL,
knots = NULL, degree = 2,
sfe = NULL, cfe = NULL,
Z = NULL, gamma = NULL, Q = NULL, kappa = NULL,
Q.type = NULL,
Q.bspline.degree = NULL,
Z.param = NULL, Q.param = NULL,
balance.period = NULL, fill.missing = FALSE,
placeboTest = FALSE, placebo.period = NULL,
carryoverTest = FALSE, carryover.period = NULL, carryover.rm = NULL,
loo = FALSE, permute = FALSE, m = 2,
normalize = FALSE, keep.sims = FALSE,
cm = FALSE,
loading.bound = "none", gamma.loading = NULL,
gamma.loading.grid = NULL,
cv.rule = "1se")
Arguments
formula |
an object of class "formula": a symbolic description of the model to be fitted, e.g, Y~D+X1+X2 |
data |
a data frame, can be a balanced or unbalanced panel data. |
Y |
the outcome indicator. |
D |
the treatment indicator. The treatment should be binary (0 and 1). |
X |
time-varying covariates. Covariates that have perfect collinearity with specified fixed effects are dropped automatically. |
W |
a string giving the column name of a weight variable. Convenience default that populates both |
W.est |
a string giving the column name of a weight variable that enters the outcome-model fit (the weighted least squares applied inside the IFE / MC / CFE solver). When |
W.agg |
a string giving the column name of a weight variable that enters the across-treated-obs aggregation ( A clean in-package solution for inverse-probability weights for confounding adjustment is under development for fect 3.0 (a cross-fit doubly-robust path); In v2.3.1, |
group |
the group indicator. If specified, the group-wise ATT will be estimated. |
na.rm |
a logical flag indicating whether to list-wise delete missing observations. Default to FALSE. If |
index |
a character vector specifying the unit (first element) and time (second element) indicators. For most methods, must be of length 2. For |
force |
a string indicating whether unit or time or both fixed effects will be imposed. Must be one of the following, "none", "unit", "time", or "two-way". The default is "two-way". |
time.component.from |
Controls which units provide the time-varying model components (time fixed effects, factor structure, temporal dynamics). Options are |
em |
a logical flag indicating whether to use the EM algorithm for missing data in the estimation sample. Default is |
r |
an integer specifying the number of factors. If |
lambda |
a single or sequence of positive numbers specifying the hyper-parameter sequence for matrix completion method. If |
nlambda |
an integer specifying the length of hyper-parameter sequence for matrix completion method. Default is |
CV |
a logical flag indicating whether cross-validation will be performed to select the optimal number of factors or hyper-parameter in matrix completion algorithm. If |
k |
an integer specifying number of cross-validation rounds. Default is |
cv.prop |
a numerical value specifying the proportion of testing set compared to sample size during the cross-validation procedure. |
cv.method |
a string specifying the cross-validation masking strategy. One of |
cv.nobs |
an integer specifying the length of continuous observations within a unit in the testing set. Default is |
cv.donut |
an integer specifying the length of removed observations at the head and tail of the continuous observations specified by |
cv.buffer |
an integer specifying the length of past-side buffer cells masked from training (but not scored) immediately before each rolling-window holdout. Used only by |
criterion |
criterion used for model selection. Default is "mspe".
|
binary |
This version doesn't support this option. |
QR |
This version doesn't support this option. |
method |
a string specifying which imputation algorithm will be used.
|
se |
a logical flag indicating whether uncertainty estimates will be produced. |
vartype |
a string specifying the type of variance estimator, e.g.
|
cl |
a string specifying the cluster for cluster bootstrapping. |
quantile.CI |
a logical flag indicating whether to use quantile confidence intervals when bootstrapping. |
nboots |
an integer specifying the number of bootstrap runs. Ignored if |
alpha |
the significance level for hypothesis tests and confidence intervals. Default |
parallel |
controls which operations run in parallel. Accepted values:
When |
cores |
an integer indicating the number of cores for parallel computing. |
tol |
a positive number indicating the tolerance level for EM updates. |
max.iteration |
the maximal number of iterations for the EM algorithm. |
seed |
an integer seed for random number generation. |
min.T0 |
an integer specifying the minimum number of pre-treatment periods for each treated unit. |
max.missing |
an integer specifying the maximum number of missing observations allowed per unit. |
proportion |
a numeric value specifying which pre-treatment periods are used for goodness-of-fit tests. |
pre.periods |
a vector specifying the range of pre-treatment periods used for the goodness-of-fit test. |
f.threshold |
a numeric threshold for an F-test in equivalence testing. Default |
tost.threshold |
a numeric threshold for two-one-sided t-tests. |
knots |
a numeric vector specifying knots (currently unused; reserved for future use). |
degree |
an integer specifying the degree (currently unused; reserved for future use). |
sfe |
vector specifying other fixed effects for |
cfe |
a vector of lists specifying interactive fixed effects for |
Z |
a vector specifying the time-invariant covariates for the Z matrix. |
gamma |
a vector specifying the time-varying covariates for the gamma matrix. |
Q |
a vector specifying the time-varying covariates for the Q matrix. |
kappa |
a vector specifying the time-invariant covariates for the kappa matrix. |
Q.type |
a vector specifying the type of Q matrix. |
Q.bspline.degree |
an integer specifying the degree used when |
Z.param |
a list specifying the parameters for the Z matrix. |
Q.param |
a list specifying the parameters for the Q matrix. |
balance.period |
a length-2 vector specifying a time range for a balanced sample. |
fill.missing |
a logical flag indicating whether to allow missing observations in a balanced sample. |
placeboTest |
a logical flag indicating whether to perform a placebo test. |
placebo.period |
an integer or 2-element numeric vector specifying pseudo-treatment periods. |
carryoverTest |
a logical flag for carryover tests. |
carryover.period |
an integer or 2-element numeric vector specifying pseudo-carryover periods. |
carryover.rm |
an integer specifying the range of post-treatment periods to treat as carryover. |
loo |
a logical flag for leave-one-period-out goodness-of-fit tests. |
permute |
a logical flag indicating whether to run a permutation test. |
m |
an integer specifying the block length for permutation tests. Default |
normalize |
a logical flag indicating whether to scale outcome and covariates. |
keep.sims |
a logical flag indicating whether to save unit-time level bootstrap effects. Default |
cm |
a logical flag indicating whether to enable causal moderation analysis. When |
loading.bound |
a string controlling whether treated-unit factor loadings are bounded inside the convex hull of control loadings. |
gamma.loading |
scalar regularization strength for the |
gamma.loading.grid |
a numeric vector of candidate |
cv.rule |
a string selecting the cross-validation rule for choosing the number of factors
Ignored when |
Details
fect implements counterfactual estimators for TSCS data. It first imputes counterfactuals by fitting an outcome model using untreated observations, then estimates the individual treatment effect as the difference between observed and predicted outcomes. Finally, it computes average treatment effects on the treated (ATT) and period-specific ATTs. Placebo and equivalence tests help evaluate identification assumptions.
Value
Y.dat |
T-by-N matrix of the outcome variable. |
D.dat |
T-by-N matrix of the treatment variable. |
I.dat |
T-by-N matrix of observation indicators (observed/missing). |
Y |
name of the outcome variable. |
D |
name of the treatment variable. |
X |
name of any time-varying covariates. |
W |
name of the weight variable. |
index |
name of the unit and time indicators. |
force |
specified fixed effects option. |
T |
number of time periods. |
N |
number of units. |
p |
number of time-varying observables. |
r.cv |
number of factors (selected by cross-validation if needed). |
lambda.cv |
optimal hyper-parameter for matrix completion, if applicable. |
beta |
coefficients for any covariates in an interactive fixed effects model. |
sigma2 |
mean squared error. |
IC |
information criterion. |
est |
results of the fitted model. |
MSPE |
mean squared prediction error from cross-validation. |
CV.out |
results of the cross-validation procedure. |
niter |
number of iterations. |
factor |
estimated time-varying factors. |
lambda |
estimated loadings. |
lambda.tr |
estimated loadings for treated units. |
lambda.co |
estimated loadings for control units. |
mu |
estimated grand mean. |
xi |
estimated time fixed effects. |
alpha |
estimated unit fixed effects. |
alpha.tr |
estimated unit fixed effects for treated units. |
alpha.co |
estimated unit fixed effects for control units. |
validX |
logical indicating if valid covariates exist. |
validF |
logical indicating if factors exist. |
id |
vector of unit IDs. |
rawtime |
vector of time periods. |
obs.missing |
matrix indicating missingness patterns. |
Y.ct |
T-by-N matrix of predicted outcomes under no treatment. |
eff |
T-by-N matrix of estimated individual treatment effects. |
res |
residuals for observed values. |
eff.pre |
effects for treated units in pre-treatment periods. |
eff.pre.equiv |
pre-treatment effects under baseline (two-way FE) model. |
pre.sd |
by-period residual standard deviations for pre-treatment ATT. |
att.avg |
overall average treatment effect on the treated. |
att.avg.W |
weighted ATT. |
att.avg.unit |
by-unit average treatment effect on the treated. |
time |
time index for switch-on treatment effect. |
count |
count of observations for each switch-on effect time. |
att |
switch-on treatment effect. |
att.on.W |
weighted switch-on effect. |
time.off |
time index for switch-off treatment effect. |
att.off |
switch-off treatment effect. |
att.off.W |
weighted switch-off effect. |
count.off |
count for each switch-off period. |
att.placebo |
ATT for placebo periods. |
att.carryover |
ATT for carryover periods. |
eff.calendar |
ATT by calendar time. |
eff.calendar.fit |
loess-fitted ATT by calendar time. |
N.calandar |
number of treated observations each calendar period. |
balance.avg.att |
ATT for balanced sample. |
balance.att |
switch-on ATT for balanced sample. |
balance.time |
time index for balanced sample. |
balance.count |
count for each time in balanced sample. |
balance.att.placebo |
ATT for placebo period in balanced sample. |
group.att |
ATT for different groups. |
group.output |
list of switch-on treatment effects by group. |
est.att.avg |
inference for |
est.att.avg.unit |
inference for |
est.att |
inference for |
est.att.W |
inference for weighted |
est.att.off |
inference for switch-off. |
est.att.off.W |
inference for weighted switch-off. |
est.placebo |
inference for placebo ATT. |
est.carryover |
inference for carryover ATT. |
est.eff.calendar |
inference for |
est.eff.calendar.fit |
inference for |
est.balance.att |
inference for balanced sample switch-on. |
est.balance.avg |
inference for balanced sample average ATT. |
est.balance.placebo |
inference for balanced sample placebo. |
est.avg.W |
inference for |
est.beta |
inference for |
est.group.att |
inference for group-specific ATT. |
est.group.output |
inference for group output. |
att.avg.boot |
bootstrap draws for |
att.avg.unit.boot |
bootstrap draws for |
att.count.boot |
bootstrap draws for |
att.off.boot |
bootstrap draws for |
att.off.count.boot |
bootstrap draws for |
att.placebo.boot |
bootstrap draws for |
att.carryover.boot |
bootstrap draws for |
balance.att.boot |
bootstrap draws for |
att.bound |
equivalence confidence interval for pre-trend. |
att.off.bound |
equivalence confidence interval for switch-off. |
beta.boot |
bootstrap draws for |
test.out |
F-test and equivalence test results for pre-treatment fit. |
loo.test.out |
leave-one-period-out test results. |
permute |
permutation test results. |
Author(s)
Licheng Liu; Ye Wang; Yiqing Xu; Ziyi Liu
References
Athey, S., Bayati, M., Doudchenko, N., Imbens, G., and Khosravi, K. (2021). Matrix completion methods for causal panel data models. Journal of the American Statistical Association, 116(536), 1716-1730.
Bai, J. (2009). Panel data models with interactive fixed effects. Econometrica, 77(4), 1229-1279.
Liu, L., Wang, Y., and Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160-176.
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.
See Also
Examples
library(fect)
data(simdata)
out <- fect(Y ~ D + X1 + X2, data = simdata,
index = c("id","time"), force = "two-way",
CV = TRUE, r = c(0, 5), se = 0, parallel = FALSE)
Internal FEct Functions
Description
Internal fect functions
Details
These are not to be called by the user (or in some cases are just waiting for proper documentation to be written :).
Over-identification test for causal moderation (cm)
Description
Implements the over-identification test described in the slide:
run two auxiliary regressions of residualized outcomes on the moderator
and covariates (including quadratic and interaction terms) with unit and
time fixed effects, then test using n \times R^2 \sim \chi^2(df),
where df is the number of *nonlinear* (quadratic + interaction) terms that
remain in the fitted model.
Usage
fect_iden(
x,
moderator,
covariates = NULL,
quadratic = TRUE,
interaction = TRUE
)
Arguments
x |
A 'fect' object. Must be estimated with 'cm=TRUE' so that 'x$est.cm' exists. |
moderator |
Character scalar. Name of the moderator |
covariates |
Optional character vector. Names of other covariates |
quadratic |
Logical. Include quadratic terms |
interaction |
Logical. Include interaction terms |
Value
A list with elements 'e1' and 'e0', each containing:
- 'n': sample size used in the auxiliary regression
- 'r2': R-squared of the auxiliary regression
- 'stat': n \times R^2
- 'df': degrees of freedom (# nonlinear terms kept)
- 'p': p-value from chi-square test
- 'model': the fitted 'fixest' model
Mean Squared Prediction Error Evaluation for fect Objects
Description
Evaluates the prediction accuracy of one or more fect model fits by hiding a subset of control observations and comparing counterfactual predictions against actual values.
Usage
fect_mspe(
out.fect,
seed = NULL,
cv.method = "rolling",
cv.nobs = 3,
cv.donut = 1,
cv.buffer = 1,
cv.prop = 0.1,
min.T0 = 5,
k = 20,
criterion = "mspe",
W = NULL,
norm.para = NULL,
proportion = 0
)
Arguments
out.fect |
A fitted |
seed |
Optional integer; random seed for reproducibility. |
cv.method |
Character; cross-validation masking strategy. One of |
cv.nobs |
Integer; number of observations to mask per unit per fold. Default is 3. |
cv.donut |
Integer; number of periods around treatment onset to exclude from masking. Used by block CV. Default is 1. |
cv.buffer |
Integer; number of past-side cells masked from training (but not scored) before each rolling-window holdout. Used only by |
cv.prop |
Numeric; for block CV, proportion of observations to mask per round; for rolling CV, fraction of eligible units sampled per fold. Default is 0.2. |
min.T0 |
Integer; minimum number of pre-treatment periods required. Default is 5. |
k |
Integer; number of cross-validation folds. Default is 5. |
criterion |
Character; scoring criterion. One of |
W |
Optional TT x N observation weight matrix. Default is |
norm.para |
Optional normalization vector. Default is |
proportion |
Numeric; proportion cutoff for count.T.cv (same as fect_cv). Default is 0. |
Value
A list containing:
summary |
A data frame with mean scores across replications for each model, including MSPE, WMSPE, GMSPE, WGMSPE, MAD, Moment, GMoment, RMSE, and Bias. |
records |
A data frame with per-replication results including Rep, Model, Hidden_N, and all score columns. |
fits |
The refitted |
criterion |
The scoring criterion used. |
scores |
The scores from the last replication. |
Examples
## Not run:
out <- fect(Y ~ D, data = df, index = c("unit", "time"), method = "ife", r = 2)
mspe <- fect_mspe(out.fect = out, hide_n = 10, seed = 42, n_rep = 5)
mspe$summary
## End(Not run)
Sensitivity Analysis for fect Objects under Relative Magnitude and Smoothness Restrictions
Description
Conducts sensitivity analyses on fect model objects under relative magnitude (RM) and smoothness (C-LF) assumptions, producing robust confidence intervals and parameter sets.
Usage
fect_sens(
fect.out,
post.periods = NA,
l_vec = NA,
Mbarvec = seq(0, 1, by = 0.1),
Mvec = seq(0, 0.25, 0.05),
periodMbarvec = c(0, 0.5),
periodMvec = c(0, 0.1),
parallel = FALSE,
cores = NULL
)
Arguments
fect.out |
A fitted |
post.periods |
Vector of post-treatment periods for sensitivity analysis. Default uses all available post-treatment periods. |
l_vec |
Optional weighting vector for averaging ATT across post-treatment periods. Default weights by treated-unit counts. |
Mbarvec |
Values of |
Mvec |
Values of |
periodMbarvec |
Values of |
periodMvec |
Values of |
parallel |
Logical; if |
cores |
Optional integer; number of workers when |
Details
This function:
Extracts ATT estimates and variance-covariance matrices from
fect.out.Constructs weighted averages across post-treatment periods.
Computes robust confidence sets under RM and C-LF assumptions.
Optionally computes robust bounds for each post-treatment period separately.
Robust sets are computed using functions from the HonestDiDFEct package.
Value
An updated fect object including:
sensitivity.rm |
Relative Magnitude (RM) sensitivity results for average and period-by-period ATT. |
sensitivity.smooth |
Smoothness (C-LF) sensitivity results for average and period-by-period ATT. |
Author(s)
Rivka Lipkovitz
Examples
## Not run:
out <- fect(Y ~ D, data = df, index = c("unit", "time"), method = "fe", se = TRUE)
out_sens <- fect_sens(
fect.out = out,
post.periods = c(1, 2, 3, 4),
Mbarvec = seq(0, 1, by = 0.2),
Mvec = c(0, 0.05, 0.1),
periodMbarvec = c(0, 0.5),
periodMvec = c(0, 0.1)
)
names(out_sens$sensitivity.rm)
names(out_sens$sensitivity.smooth)
## End(Not run)
Obatin the Cohort Index
Description
Obtain the cohort index based on the provided panel data.
Usage
get.cohort(data, D, index,
varname = NULL,
start0 = FALSE,
entry.time = NULL,
drop.always.treat = FALSE)
Arguments
data |
a data frame, can be a balanced or unbalanced panel data. |
D |
the treatment indicator. The treatment should be binary (0 and 1). |
index |
a two-element string vector specifying the unit and time indicators. Must be of length 2. Every observation should be uniquely defined by the pair of the unit and time indicator. |
varname |
a vector of strings that specifies the variable names for the cohort index and relative periods to be generated. |
start0 |
a logical flag that indicates whether period 0 is the first post-treatment period. By default, it is set to FALSE, meaning that period 1 is considered the initial post-treatment period. |
entry.time |
a list of intervals representing the initial calendar time of treatment for each cohort. Units that received treatment within each specified interval are categorized as belonging to a single cohort. |
drop.always.treat |
a logical flag that indicates whether to drop all always-treated units. |
Details
get.cohort function preprocesses the data and generates the cohort index for different groups. If not specified in varname, the function automatically creates four new variables: 'FirstTreat' stores the initial calendar time when a unit is first treated, 'Cohort' stores the cohort time, 'Time_to_Treatment' tracks the period relative to the treatment, and 'Time_to_Exit' tracks the period relative to the treatment exit. Users have the option to specify custom names for these newly generated variables using the varname parameter. By default, the function sets start0=FALSE, where the relative period 1 corresponds to the first post-treatment/post-exit-treatment period. If start0=TRUE, period 0 becomes the first post-treatment/post-exit-treatment period. Additionally, users can categorize units into specific cohorts using the entry.time parameter. For instance, if entry.time=list(c(1,5),c(6,10)), units that receive their first treatment within the calendar intervals c(1,5) and c(6,10) are grouped into two distinct cohorts. Units that have never been treated are always categorized as the "control cohort".
Value
data |
a new data frame containing the cohort index. |
Author(s)
Licheng Liu; Yiqing Xu, Ziyi Liu; Zhongyu Yin
Simulated Gsynth-like Panel Data (No Reversal)
Description
A simulated dataset for demonstration and testing.
Format
data.frame
Simulated Panel Data Example
Description
A simulated dataset used in package vignettes and examples.
Format
data.frame
Imputed Potential Outcomes Accessor
Description
Returns the cell-level imputed potential-outcome surface from a fitted
fect object as a long-form data frame. This is the rock-bottom
accessor for any post-hoc estimand: read off the columns and aggregate
however you like. Used internally by estimand for the
shipped estimand types; exposed publicly so users can compose custom
estimands the package does not ship.
Usage
imputed_outcomes(
fit,
cells = NULL,
replicates = FALSE,
direction = c("on", "off")
)
Arguments
fit |
A |
cells |
Optional filter on which treated cells to return. Accepts
|
replicates |
Logical. |
direction |
Either |
Value
A data frame with one row per treated cell or per (treated cell, replicate). Columns:
idUnit identifier from
fit$id.timeCalendar time from
fit$rawtime.event.timeEvent time at this cell (relative to onset or exit per
direction).cohortFirst-treatment calendar time for the unit (
direction = "on") or first-exit calendar time (direction = "off").treatedLogical; always
TRUEin returned rows.Y_obsObserved outcome at this cell.
Y0_hatImputed counterfactual outcome (
Y_obs - eff).effCell-level score: contribution to the ATT estimator. For imputation estimators this equals
Y_obs - Y0_hat; for doubly-robust estimators it equals(Y_obs - Y0_hat) + eff_debias.eff_debiasDebias correction; 0 for plain imputation estimators, populated for DR estimators.
W.aggAggregation weight at this cell; 1 if the fit was built without
WorW.agg.replicate(only when
replicates = TRUE) 1..nbootsfor bootstrap, or the dropped-unit index for jackknife.
Memory cost
With replicates = TRUE the returned data frame has
n_treated_cells * nboots rows. For typical panels this is
manageable; for large panels (TT \times N \ge 50{,}000 and
nboots \ge 500) consider filtering via cells
before expansion.
Slot contract
This function reads from fit$Y.dat, fit$D.dat,
fit$T.on (or T.off), fit$eff,
fit$eff.boot (when replicates = TRUE),
fit$eff_debias (when populated), fit$W.agg,
fit$id, fit$rawtime. These slots have a documented
stable shape; see the package design notes.
See Also
estimand for the typed dispatcher built on top of this
accessor; fect for the fitting interface.
Examples
## Not run:
library(fect)
fit <- fect(Y ~ D, data = simdata, index = c("id", "time"),
method = "fe", force = "two-way",
se = TRUE, nboots = 200, parallel = FALSE,
keep.sims = TRUE)
## Point-estimate long form: one row per treated cell.
po <- imputed_outcomes(fit)
head(po)
## Filter to first 5 event times.
po5 <- imputed_outcomes(fit, cells = ~ event.time %in% 1:5)
## Bootstrap replicate expansion (requires keep.sims = TRUE).
po_b <- imputed_outcomes(fit, replicates = TRUE)
nrow(po_b) == nrow(po) * 200 # one row per (cell, replicate)
## End(Not run)
Interactive Fixed Effects Models
Description
Estimating interactive fixed effect models.
Usage
interFE(formula = NULL, data, Y, X = NULL, W = NULL,
index, r = 0, force = "two-way",
se = FALSE, nboots = 500, seed = NULL,
tol = 1e-3, max_iteration = 500,
binary = FALSE, QR = FALSE, normalize = FALSE)
Arguments
formula |
an object of class "formula": a symbolic description of the model to be fitted. |
data |
a data frame. |
Y |
outcome variable. |
X |
time-varying covariates. |
W |
weights. |
index |
a two-element string vector specifying the unit (group) and time indicators. |
r |
an integer specifying the number of factors. |
force |
a string indicating whether unit/time/both fixed effects will be imposed: "none", "unit", "time", or "two-way". |
se |
logical; if |
nboots |
number of bootstrap runs (ignored if |
seed |
random seed. |
tol |
tolerance for EM algorithm. |
max_iteration |
max number of EM iterations. |
binary |
logical flag for a probit link (not fully supported here). |
QR |
logical flag for QR-based factor analysis in probit model (not fully supported). |
normalize |
logical; if |
Details
interFE estimates interactive fixed effect models as in Bai (2009).
Value
beta |
estimated coefficients. |
mu |
estimated grand mean. |
factor |
estimated time-varying factors. |
lambda |
estimated factor loadings. |
VNT |
diagonal matrix of r eigenvalues. |
niter |
number of iterations before convergence. |
alpha |
estimated unit fixed effects (if imposed). |
xi |
estimated time fixed effects (if imposed). |
residuals |
model residuals. |
sigma2 |
residual mean squared error. |
IC |
information criterion. |
ValidX |
logical for whether valid covariates exist. |
dat.Y |
matrix of outcome data. |
dat.X |
array of independent variables. |
Y |
name of the outcome variable. |
X |
name of time-varying control variables. |
index |
name of unit/time indicators. |
est.table |
table of final estimates. |
est.boot |
matrix of bootstrap results. |
Author(s)
Licheng Liu; Ye Wang; Yiqing Xu
References
Bai, J. (2009). Panel data models with interactive fixed effects. Econometrica, 77(4), 1229-1279.
See Also
Examples
library(fect)
data(simdata)
d <- simdata[-(1:150),] # remove the treated units
out <- interFE(Y ~ X1 + X2, data = d, index=c("id","time"),
r = 2, force = "two-way", nboots = 50)
Plot Method for 'fect' Objects
Description
Visualizes results from a fect estimation.
Usage
## S3 method for class 'fect'
plot(
x,
type = NULL,
restrict = "rm",
loo = FALSE,
highlight = NULL,
highlight.fill = FALSE,
plot.ci = NULL,
show.points = TRUE,
loess.fit = TRUE,
show.group = NULL,
bound = NULL,
show.count = TRUE,
proportion = 0.3,
pre.periods = NULL,
f.threshold = NULL,
tost.threshold = NULL,
effect.bound.ratio = FALSE,
stats = NULL,
stats.labs = NULL,
raw = "none",
vis = NULL,
main = NULL,
xlim = NULL,
ylim = NULL,
xlab = NULL,
ylab = NULL,
xangle = NULL,
yangle = NULL,
xbreaks = NULL,
ybreaks = NULL,
xticklabels = NULL,
yticklabels = NULL,
gridOff = NULL,
legendOff = FALSE,
legend.pos = NULL,
legend.nrow = NULL,
legend.labs = NULL,
stats.pos = NULL,
show.stats = TRUE,
theme.bw = TRUE,
nfactors = NULL,
include.FE = TRUE,
id = NULL,
cex.main = NULL,
cex.main.sub = NULL,
cex.axis = NULL,
cex.lab = NULL,
cex.legend = NULL,
cex.text = NULL,
axis.adjust = FALSE,
axis.lab = "both",
axis.lab.gap = c(0, 0),
shade.post = FALSE,
start0 = FALSE,
return.test = FALSE,
return.data = FALSE,
balance = NULL,
weight = NULL,
lcolor = NULL,
lwidth = NULL,
ltype = NULL,
line.color = NULL,
line.width = NULL,
count = NULL,
preset = NULL,
connected = NULL,
ci.outline = FALSE,
color = NULL,
pre.color = NULL,
post.color = NULL,
est.lwidth = NULL,
est.pointsize = NULL,
count.color = NULL,
count.alpha = NULL,
count.outline.color = NULL,
placebo.color = NULL,
carryover.color = NULL,
carryover.rm.color = NULL,
sens.original.color = NULL,
sens.colors = NULL,
counterfactual.color = NULL,
counterfactual.raw.controls.color = NULL,
counterfactual.raw.treated.color = NULL,
counterfactual.linetype = NULL,
box.control = NULL,
box.treat = NULL,
calendar.color = NULL,
calendar.lcolor = NULL,
calendar.cicolor = NULL,
heterogeneous.color = NULL,
heterogeneous.lcolor = NULL,
heterogeneous.cicolor = NULL,
equiv.color = NULL,
status.treat.color = NULL,
status.control.color = NULL,
status.missing.color = NULL,
status.removed.color = NULL,
status.placebo.color = NULL,
status.carryover.color = NULL,
status.carryover.rm.color = NULL,
status.balanced.post.color = NULL,
status.balanced.pre.color = NULL,
status.background.color = NULL,
covariate = NULL,
covariate.labels = NULL,
covariate.value = NULL,
covariate.value.range = FALSE,
relative.time = FALSE,
pretreatment = FALSE,
num.pretreatment = 3,
cm = FALSE,
legacy.style = FALSE,
...
)
Arguments
x |
A fitted |
type |
Plot type. Options include: |
restrict |
For sensitivity plots ( |
loo |
Logical; if |
highlight |
Controls which test-period types receive the colored-glyph treatment in placebo / carryover plots. Accepts:
|
highlight.fill |
Logical. If |
plot.ci |
Specifies the confidence interval to be plotted. Options include:
|
show.points |
Logical; if |
show.group |
Optional character string or |
bound |
Which bounds to display in bounding/equivalence tests:
|
show.count |
Logical; if |
proportion |
Numeric (0 to 1); for event study plots, restricts plotted time points to those where the number of treated units is at least this fraction of the maximum number of treated units observed across all periods. Default is |
pre.periods |
Optional numeric vector; specifies pre-treatment periods to be used for bounding and equivalence tests. Default is |
f.threshold |
Numeric or |
tost.threshold |
Numeric or |
effect.bound.ratio |
Logical; if |
stats |
Character vector or |
stats.labs |
Character vector or |
raw |
For |
vis |
(Deprecated) Formerly controlled line display for placebo/carryover tests. This is now handled by |
main |
Character string or |
xlim |
Numeric vector of length 2 or |
ylim |
Numeric vector of length 2 or |
xlab |
Character string or |
ylab |
Character string or |
xangle |
Numeric or |
yangle |
Numeric or |
xbreaks |
Numeric vector or |
ybreaks |
Numeric vector or |
xticklabels |
Character vector or |
yticklabels |
Character vector or |
gridOff |
Logical or |
legendOff |
Logical; if |
legend.pos |
Character string or |
legend.nrow |
Integer or |
legend.labs |
Character vector or |
stats.pos |
Numeric vector of length 2 or |
show.stats |
Logical; if |
theme.bw |
Logical; if |
nfactors |
Integer or |
include.FE |
Logical; if |
id |
Character vector or |
cex.main |
Numeric or |
cex.main.sub |
Numeric or |
cex.axis |
Numeric or |
cex.lab |
Numeric or |
cex.legend |
Numeric or |
cex.text |
Numeric or |
axis.adjust |
Logical; if |
axis.lab |
Controls axis labeling in |
axis.lab.gap |
Numeric vector of length 1 or 2; gap spacing for axis labels in |
shade.post |
Logical; if |
start0 |
Logical; if |
return.test |
Logical; if |
return.data |
Logical; if |
balance |
Logical or |
weight |
Logical or |
lcolor |
Character vector of length 1 or 2, or |
lwidth |
Numeric vector of length 1 or 2, or |
ltype |
Character vector of length 1 or 2, or |
line.color |
(Deprecated) Use |
line.width |
(Deprecated) Use |
count |
(Deprecated) Use |
preset |
A character string specifying a color and style preset: |
connected |
Logical or |
ci.outline |
Logical; if |
color |
Character string or |
pre.color |
Character string or |
post.color |
Character string or |
est.lwidth |
Numeric or |
est.pointsize |
Numeric or |
count.color |
Character string or |
count.alpha |
Numeric (0-1) or |
count.outline.color |
Character string or |
placebo.color |
Character string or |
carryover.color |
Character string or |
carryover.rm.color |
Character string or |
sens.original.color |
Character string or |
sens.colors |
Vector of colors or |
counterfactual.color |
Character string or |
counterfactual.raw.controls.color |
Character string or |
counterfactual.raw.treated.color |
Character string or |
counterfactual.linetype |
Character string or |
box.control |
Character string or |
box.treat |
Character string or |
calendar.color |
Character string or |
calendar.lcolor |
Character string or |
calendar.cicolor |
Character string or |
heterogeneous.color |
Character string or |
heterogeneous.lcolor |
Character string or |
heterogeneous.cicolor |
Character string or |
equiv.color |
Character string or |
status.treat.color |
Character string or |
status.control.color |
Character string or |
status.missing.color |
Character string or |
status.removed.color |
Character string or |
status.placebo.color |
Character string or |
status.carryover.color |
Character string or |
status.carryover.rm.color |
Character string or |
status.balanced.post.color |
Character string or |
status.balanced.pre.color |
Character string or |
status.background.color |
Character string or |
covariate |
Character string or |
covariate.labels |
Character vector or |
covariate.value |
Numeric or |
covariate.value.range |
Logical; if |
relative.time |
Logical; if |
pretreatment |
Logical; if |
num.pretreatment |
Integer; number of pre-treatment periods to include when |
cm |
Logical; if |
legacy.style |
Logical; if |
loess.fit |
Logical; if |
... |
Additional graphical parameters passed to internal plotting routines, primarily those accepted by |
Details
plot.fect generates various visualizations for objects estimated via fect. Depending on
the selected type, it can show treatment-effect dynamics ("gap", "exit", "cumul"),
equivalence test outcomes ("equiv"), factor/loadings for factor models ("factors", "loadings"),
raw vs. counterfactual trajectories ("counterfactual"), treatment status ("status"),
effects by calendar time ("calendar"), distribution of individual effects ("box"),
or sensitivity analysis results ("sens", "sens_es").
The preset argument allows for quick customization of plot aesthetics using predefined color schemes.
Many individual color and style parameters can be set to further customize the appearance, and these will override any settings from a preset or the base style.
The function heavily relies on ggplot2 for plotting and esplot for event-study style visualizations.
Value
By default, a ggplot2 object representing the plot.
If return.data=TRUE, returns a list containing:
p |
The |
data |
A named list of data frames containing the data used to construct each layer of the plot (no extra all-NA columns are added). |
If return.test=TRUE as well, the list also contains:
test.out |
A list or data frame containing relevant test statistics (such as F-tests, equivalence p-values, placebo test p-values, etc.), if applicable to the plot type and options chosen. |
If return.test=TRUE and return.data=FALSE, returns a list containing p and test.out.
Author(s)
Licheng Liu, Ye Wang, Yiqing Xu, Ziyi Liu, Rivka Lipkovitz
References
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57–76.
Liu, L., Wang, Y., & Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data.
American Journal of Political Science, 66(1), 220-237. (Provides context for esplot which is used internally for many plot types)
Rambachan, A., & Roth, J. (2023). A More Credible Approach to Parallel Trends.
Review of Economic Studies, 90(5), 2555-2591. (Provides context for sensitivity analysis plots like type="sens" and type="sens_es")
Examples
library(fect)
# For CRAN checks, use a small number of bootstraps
# In practice, use a larger number (e.g., nboots = 200 or more)
if(requireNamespace("ggplot2") && requireNamespace("ggrepel")) {
data(simdata)
# Estimate with fixed effects method
out.fect <- fect(
Y ~ D + X1 + X2,
data = simdata,
index = c("id","time"),
method = "fe",
force = "two-way",
se = TRUE,
parallel = FALSE,
nboots = 5 # nboots low for example
)
# Default gap plot
plot(out.fect, main = "Estimated ATT (FEct)", ylab = "Effect of D on Y")
# Gap plot with vibrant preset and custom line color
# plot(out.fect, preset = "vibrant", color = "darkgreen",
# main = "Estimated ATT (Vibrant Preset, Custom Line)")
# Counterfactual plot for the first treated unit
# Need to know the ID of a treated unit. Let's find one.
treated_ids <- unique(simdata$id[simdata$D == 1])
if (length(treated_ids) > 0) {
plot(out.fect, type = "counterfactual", id = treated_ids[1],
main = paste("Counterfactual for Unit", treated_ids[1]))
}
# Status plot
plot(out.fect, type = "status")
# Cumulative effect plot (if est.eff is available from fect call)
# This example might not have it by default, but showing how to call
# out.fect.cumul <- fect(Y ~ D, data = simdata, index = c("id","time"), method = "fe",
# cumulative = TRUE, se = TRUE, parallel = FALSE, nboots = 5)
# if (exists("out.fect.cumul")) {
# plot(out.fect.cumul, type = "cumul", main = "Cumulative ATT")
# }
# Example for sensitivity plot (requires IFE/GSYNTH method and sensitivity analysis)
# \donttest{
# out.ife <- fect(Y ~ D, data = simdata, index = c("id","time"),
# method = "ife", se = TRUE, r = 2,
# sensitivity.analysis = TRUE, sensitivity.plot = FALSE, # run analysis
# parallel = FALSE, nboots = 5) # nboots low for example
# if (!is.null(out.ife$sensitivity.rm)) {
# plot(out.ife, type = "sens", restrict = "rm",
# main = "Sensitivity Analysis (Relative Magnitude)")
# plot(out.ife, type = "sens_es", restrict = "rm",
# main = "Event-Study Sensitivity (Relative Magnitude)")
# }
# }
}
Print Results
Description
Print results of the matrix completion method.
Usage
## S3 method for class 'fect'
print(x, switch.on = TRUE,
switch.off = FALSE,time.on.lim = NULL, time.off.lim = NULL, ...)
Arguments
x |
a |
switch.on |
logical; if |
switch.off |
logical; if |
time.on.lim |
two-element numeric vector specifying the switch-on effect range. |
time.off.lim |
two-element numeric vector specifying the switch-off effect range. |
... |
other arguments. |
Value
No return value.
Author(s)
Licheng Liu; Ye Wang; Yiqing Xu; Ziyi Liu
References
Athey, S., Bayati, M., Doudchenko, N., Imbens, G., and Khosravi, K. (2021). Matrix completion methods for causal panel data models. Journal of the American Statistical Association, 116(536), 1716-1730.
Bai, J. (2009). Panel data models with interactive fixed effects. Econometrica, 77(4), 1229-1279.
Liu, L., Wang, Y., and Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160-176.
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.
See Also
Examples
library(fect)
data(simdata)
out <- fect(Y ~ D + X1 + X2, data = simdata,
index = c("id","time"), force = "two-way",
CV = TRUE, r = c(0, 5), se = 0, parallel = FALSE)
print(out)
Print Results
Description
Print results of interactive fixed effects estimation.
Usage
## S3 method for class 'interFE'
print(x, ...)
Arguments
x |
an |
... |
other arguments. |
Value
No return value.
Author(s)
Licheng Liu; Ye Wang; Yiqing Xu
References
Bai, J. (2009). Panel data models with interactive fixed effects. Econometrica, 77(4), 1229-1279.
See Also
Examples
library(fect)
data(simdata)
d <- simdata[-(1:150),] # remove the treated units
out <- interFE(Y ~ X1 + X2, data = d, index=c("id","time"),
r = 2, force = "two-way", nboots = 50)
print(out)
Rolling-window cross-validation for rank selection
Description
Picks the number of factors 'r' for an interactive-fixed-effects model via standard rolling-window cross-validation. For each of 'k' folds, a fraction 'cv.prop' of eligible units (controls plus treated pre-treatment) is sampled; only sampled units carry a mask. For each sampled unit, a random anchor time 't*' is drawn and the fold's training set excludes 't* - cv.buffer, ..., t* - 1' (buffer), 't*, ..., t* + cv.nobs - 1' (the held-out, scored block), and 't* + cv.nobs, ..., end_of_eligible(t)' (rolling-window future drop; for treated units, 'end_of_eligible' is the cell strictly before treatment onset). MSPE is scored at the held-out block only and averaged across folds.
Usage
r.cv.rolling(
formula,
data,
index,
method = c("ife", "gsynth", "cfe"),
r.max = 5L,
cv.nobs = 3L,
cv.buffer = 1L,
k = 20L,
cv.prop = 0.1,
cv.rule = c("1se", "min", "1pct"),
min.T0 = 5L,
force = "unit",
seed = NULL,
verbose = TRUE,
...
)
Arguments
formula |
A model formula, e.g. 'Y ~ D + X1 + X2'. |
data |
A long-format data frame. |
index |
Character vector identifying the panel structure. For 'method = "ife"' and 'method = "gsynth"', length 2: 'c("unit", "time")'. For 'method = "cfe"', length >= 2: the first two entries are 'c("unit", "time")' and any additional entries are extra grouping fixed-effect columns forwarded to the inner ‘fect()' call’s 'index =' argument. |
method |
Estimator. One of '"ife"' (IFE-EM, internally 'time.component.from = "notyettreated"'), '"gsynth"' (GSC, internally 'time.component.from = "nevertreated"'), or '"cfe"' (Complex Fixed Effects, internally 'time.component.from = "notyettreated"'). All three paths populate 'Y.ct.full' at masked positions, so MSPE scoring works uniformly. For CFE, rolling CV picks 'r' only; CFE-specific arguments ('Z', 'gamma', 'Q', 'Q.type', 'kappa', extra index columns) are forwarded via '...' and held fixed at their user-supplied values. |
r.max |
Largest candidate rank to evaluate. CV is run over '0:r.max'. |
cv.nobs |
Length of the held-out (scored) block per unit per fold. Default 3. |
cv.buffer |
Number of observations immediately BEFORE the held-out block to drop from training (the past-side buffer that attenuates AR-leakage). Default 1. Analogous to 'cv.donut' in the existing 'cv.method = "all_units"' / '"treated_units"' strategies, but applied only on the past side: the future side is dropped by construction. |
k |
Number of folds. Each fold draws a fresh sample of units and a fresh set of per-unit anchors; the per-r MSPE is averaged across folds and the SE used by the '"1se"' rule reflects fold-to-fold variability. Default 20 (matches the default for the existing CV strategies). |
cv.prop |
Fraction of eligible units sampled per fold. Only sampled units receive a mask in that fold; the rest stay fully observed and contribute training data at every period. Default 0.1 (paired with 'k = 20' for ~2x coverage of every eligible unit across folds). Across 'k' folds, every eligible unit lands in the holdout roughly 'k * cv.prop' times in expectation. Must satisfy '0 < cv.prop <= 1'. On small panels (n_eligible < 30) consider raising further, since per-fold MSPE precision scales with 'cv.prop * n_eligible * cv.nobs'. |
cv.rule |
Rule for picking 'r' from the MSPE curve: '"1se"' (default), '"min"', or '"1pct"'. |
min.T0 |
Minimum observations required strictly before the anchor. Sets the lower bound on valid anchor positions. Default 5. |
force |
One of '"none"', '"unit"', '"time"', '"two-way"'. Default '"unit"'. |
seed |
Optional integer base seed; per-fold seeds derive from 'seed + fold_id' for reproducibility. Default 'NULL' (use the ambient RNG). |
verbose |
If TRUE (default), print per-fold per-r MSPE. |
... |
Additional arguments forwarded to 'fect()'. For 'method = "cfe"', the user holds CFE structural arguments ('Z', 'gamma', 'Q', 'Q.type', 'Q.bspline.degree', 'kappa', etc.) fixed at their spec via '...'; rolling CV varies only 'r'. |
Details
Per-fold unit sampling is required: masking every eligible unit at the same time leaves no donor data at the masked time points and breaks factor identification. Sampling 'cv.prop' of units per fold keeps unsampled units fully observed at all periods.
This is the standard time-series CV design (cf. 'forecast::tsCV', 'tidymodels::sliding_window', 'caret::createTimeSlices') adapted to panel data: each sampled unit gets its own anchor per fold, drawn uniformly from valid positions.
Value
List with components: - 'r.cv': chosen rank. - 'cv.rule': rule applied. - 'mspe': data.frame of per-r MSPE (averaged across folds), SE across folds, and held-out cell counts. - 'mspe.per.fold': r-by-k matrix of per-fold MSPE. - 'k', 'cv.nobs', 'cv.buffer', 'cv.prop': parameters used. - 'n.units.masked': distinct units that contributed to at least one fold's holdout.
Examples
## Not run:
library(fect)
data(simdata)
res <- r.cv.rolling(Y ~ D, data = simdata, index = c("id", "time"),
method = "ife", r.max = 5,
cv.nobs = 3, cv.buffer = 1, k = 20)
res$r.cv
## then use the chosen r in a CV-disabled fit:
fit <- fect(Y ~ D, data = simdata, index = c("id", "time"),
method = "ife", time.component.from = "notyettreated",
CV = FALSE, r = res$r.cv, se = TRUE)
## End(Not run)
Simulated data (no interactive fixed effects)
Description
A simulated dataset with continuous outcomes and no interactive fixed effects (factor loadings set to zero). Same DGP as simdata but with the factor contribution removed from the outcome.
Format
dataframe
References
Liu, L., Wang, Y., and Xu, Y. (2022). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160-176.
Simulated data for Gsynth (no treatment reversal)
Description
A simulated dataset with no treatment reversal, used to demonstrate the generalized synthetic control method (never-treated estimation regime).
Format
dataframe
References
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.
Simulated panel data with unit-specific linear time trends (block DID)
Description
A simulated balanced panel with 200 units and 50 time periods.
All 80 treated units receive treatment at period 41 (block DID design).
The DGP includes unit-specific slopes on a linear time trend,
where treated units have systematically steeper slopes.
Used to demonstrate unit-specific time trends with Q.type = "linear" in the CFE estimator.
Format
A data frame with 10000 rows and 4 columns:
- time
Time period (1 to 50)
- id
Unit identifier (1 to 200)
- Y
Outcome variable
- D
Treatment indicator (0/1)
Simulated unbalanced panel with region-specific time effects
Description
A simulated unbalanced panel with 500 units belonging to 5 regions and 20 time periods. The DGP includes region-specific linear time trends as the confounding source. Treatment probability and timing depend on region, and units in higher-numbered regions enter the panel later, creating unbalancedness. Used to demonstrate additional fixed effects in the CFE estimator.
Format
A data frame with columns:
- time
Time period (1 to 20)
- id
Unit identifier (1 to 500)
- region
Region indicator (1 to 5)
- Y
Outcome variable
- D
Treatment indicator (0/1)
- region_time
Region-by-time interaction factor
Simulated panel data with unit-specific sinusoidal time trends (block DID)
Description
A simulated balanced panel with 200 units and 50 time periods. All 80 treated units receive treatment at period 41 (block DID design). The DGP includes unit-specific amplitudes on a half-cycle sinusoidal time trend, where treated units have systematically larger amplitudes.
Format
A data frame with 10000 rows and 4 columns:
- id
Unit identifier (1 to 200)
- time
Time period (1 to 50)
- Y
Outcome variable
- D
Treatment indicator (0/1)
Simulated panel data with two latent factors
Description
A simulated panel dataset with continuous outcomes used throughout the package vignettes to demonstrate factor-augmented counterfactual estimators. The data-generating process follows Liu, Wang, and Xu (2024) with one modification (see Format).
The panel has N = 200 units and T = 35 time periods.
Treatment switches on and off over time (99 of 150 treated units
experience at least one reversal), reflecting a general treatment
pattern rather than simple staggered adoption. The outcome includes two
latent factors (r = 2), so the parallel-trends assumption is
violated and the standard fixed-effects estimator is biased. Treatment
assignment loads on the same factors and fixed effects that enter the
outcome—units with larger \lambda_i and \alpha_i are more
likely to be treated—so the confounding is structural and cannot be
removed by two-way fixed effects alone.
Format
A data frame with the following columns:
- id
unit identifier (1–200)
- time
time period (1–35)
- Y
observed outcome
- error
idiosyncratic error
\varepsilon_{it} \sim N(0, 2)- eff
realized treatment effect
\tau_{it}- tr_cum, tr_prob
treatment-probability constructions
- D
treatment indicator
- X1, X2
observed time-varying covariates
\sim N(0, 1)with coefficients 1 and 3- alpha
unit fixed effect
\alpha_i \sim N(0, 1)- xi
time fixed effect
\xi_t(AR(1) with drift)- F1, F2
latent time factors
f_t \in \mathbb{R}^2(one trending, one white noise)- L1, L2
unit-specific factor loadings
\lambda_i \sim N(0.5, 1)- FL1, FL2
per-cell factor-loading products
\lambda_{i,k} \cdot f_{t,k}(k = 1, 2)
The DGP is
Y_{it} = \tau_{it} D_{it} + X_{1,it} + 3 X_{2,it} + \mu
+ 3\alpha_i + \xi_t
+ 2\, \lambda_i' f_t + \varepsilon_{it},
with grand mean \mu = 5 and treatment effect
\tau_{it} \sim N(0.4 \cdot \mathrm{tr\_cum}_{it}/T,\; 0.2).
The 2\, \lambda_i' f_t term doubles the latent factor contribution
relative to the original Liu, Wang, and Xu (2024) DGP. The doubling
strengthens the factor signal-to-noise ratio (variance of the factor
contribution to variance of the residual) from approximately 2.7 to
10.9, which makes the factor structure clearly recoverable by
cross-validated rank-selection procedures on this dataset. The
unmodified DGP is preserved in earlier package versions; see
git log data/simdata.rda for the prior file.
References
Liu, L., Wang, Y., and Xu, Y. (2024). A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data. American Journal of Political Science, 68(1), 160–176.
Simulated data for Gsynth
Description
A simulated dataset with no treatment reversal.
Format
dataframe
References
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.
EDR and Voter Turnout in the US
Description
State-level voter turnout data.
Format
dataframe
References
Springer, M. J. (2014). How the States Shaped the Nation: American Electoral Institutions and Voter Turnout, 1920-2000. University of Chicago Press.
Xu, Y. (2017). Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models. Political Analysis, 25(1), 57-76.