Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 337 additions & 0 deletions ARCHITECTURE.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion vignettes/01-start.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ ls()

### Simulated datasets

The package includes five simulated panel datasets. The first two (`simdata` and `sim_base`) are generated from the data-generating process (DGP) in @LWX2022. Both have $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 remaining three (`sim_trend`, `sim_region`, `sim_linear`) are block DID designs used to demonstrate CFE model components.
The package includes five simulated panel datasets. The first two (`simdata` and `sim_base`) are generated from the data-generating process (DGP) in @LWX2024. Both have $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 remaining three (`sim_trend`, `sim_region`, `sim_linear`) are block DID designs used to demonstrate CFE model components.

The full DGP for `simdata` is: $$Y_{it} = \tau_{it} D_{it} + X_{1,it} + 3 X_{2,it} + \mu + 3\alpha_i + \xi_t + \lambda_i' f_t + \varepsilon_{it}$$ where $\alpha_i \sim N(0,1)$ are unit fixed effects, $\xi_t$ follows an AR(1) process with drift (time fixed effects), $X_{1,it}$ and $X_{2,it} \sim N(0,1)$ are observed covariates with coefficients 1 and 3, $\lambda_i \in \mathbb{R}^2$ are unit-specific factor loadings drawn from $N(0.5, 1)$, $f_t \in \mathbb{R}^2$ are latent time factors (one trending, one white noise), and $\varepsilon_{it} \sim N(0,2)$. The treatment effect is heterogeneous, i.e., $\tau_{it} \sim N(0.4 \cdot \text{tr\_cum}_{it}/T,\; 0.2)$, where $\text{tr\_cum}_{it}$ counts cumulative treatment periods. The grand mean is $\mu = 5$.

Expand Down
20 changes: 18 additions & 2 deletions vignettes/02-fect.Rmd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The Imputation Estimator {#sec-fect}

In this chapter, we illustrate how to use the **fect** package to implement counterfactual estimators (or imputation estimators) and conduct diagnostic tests proposed by @LWX2022 [<a href="https://onlinelibrary.wiley.com/doi/full/10.1111/ajps.12723" target="_blank">Paper</a>]. R script used in this chapter can be downloaded [here](https://raw.githubusercontent.com/xuyiqing/fect/dev/vignettes/rscript/02-fect.R).
In this chapter, we illustrate how to use the **fect** package to implement counterfactual estimators (or imputation estimators) and conduct diagnostic tests proposed by @LWX2024 [<a href="https://onlinelibrary.wiley.com/doi/full/10.1111/ajps.12723" target="_blank">Paper</a>]. R script used in this chapter can be downloaded [here](https://raw.githubusercontent.com/xuyiqing/fect/dev/vignettes/rscript/02-fect.R).

## Simulated data

Expand Down Expand Up @@ -347,7 +347,6 @@ We can then visualize the weighted dynamic treatment effects using the inbuilt f
plot(out.w, main = "Estimated Weighted ATT")
```

------------------------------------------------------------------------

## Additional notes

Expand All @@ -356,3 +355,20 @@ plot(out.w, main = "Estimated Weighted ATT")
2. We can get replicable results by setting the option `seed` to a certain integer, no matter whether the parallel computing is used.

3. When `na.rm = FALSE` (default), the program allows observations to have missing outcomes $Y$ but not $X$ or treatment statuses $D$. When `na.rm = TRUE` the program will drop all observations that have missing values in outcomes, treatments, or covariates.


## How to Cite

If you find these methods helpful, you can cite @LWX2024.

```bibtex
@article{LWX2024,
title = {A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data},
author = {Liu, Licheng and Wang, Ye and Xu, Yiqing},
journal = {American Journal of Political Science},
volume = {68},
number = {1},
pages = {160--176},
year = {2024}
}
```
16 changes: 16 additions & 0 deletions vignettes/03-ife-mc.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,19 @@ In the above plot, the three periods in blue are dropped from the first-stage es
- The `proportion` option controls which pre-treatment periods are included in the tests (default: periods where the number of treated units exceeds `proportion` $\times$ total treated units).
- The `tost.threshold` option sets the equivalence range for the TOST test (default: $0.36\hat{\sigma}_\epsilon$). Finding the "right" threshold is often a challenge in empirical research.
:::

## How to Cite

If you find these methods helpful, you can cite @LWX2024.

```bibtex
@article{LWX2024,
title = {A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data},
author = {Liu, Licheng and Wang, Ye and Xu, Yiqing},
journal = {American Journal of Political Science},
volume = {68},
number = {1},
pages = {160--176},
year = {2024}
}
```
20 changes: 19 additions & 1 deletion vignettes/06-plots.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ plot(out, type = "counterfactual",

## Pretrend Tests {#sec-pretrend}

We provide two tests that shed light on the parallel trends assumption: the placebo test and the equivalence test. For methodological details, see @sec-fect or @LWX2022.
We provide two tests that shed light on the parallel trends assumption: the placebo test and the equivalence test. For methodological details, see @sec-fect or @LWX2024.

### Placebo test---shape markers

Expand Down Expand Up @@ -614,3 +614,21 @@ The table below summarizes which parameters apply to each plot type. Parameters
| `status.*.color` | --- | --- | --- | --- | --- | --- | Yes | --- | --- | --- |
| `xbreaks` / `ybreaks` | Yes | Yes | Yes | Yes | Yes | Yes | --- | --- | --- | Yes |
| `xlim` / `ylim` | Yes | Yes | Yes | Yes | Yes | Yes | --- | Yes | --- | Yes |



## How to Cite

If you find these methods and visualization tools helpful, you can cite @LWX2024.

```bibtex
@article{LWX2024,
title = {A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data},
author = {Liu, Licheng and Wang, Ye and Xu, Yiqing},
journal = {American Journal of Political Science},
volume = {68},
number = {1},
pages = {160--176},
year = {2024}
}
```
18 changes: 17 additions & 1 deletion vignettes/07-gsynth.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,6 @@ print(mspe.comp$summary[, c("Model", "MSPE", "RMSE", "MAD")])

Since `sim_gsynth` follows a pure IFE data generating process with two factors, Models 1 and 2 should produce identical MSPE --- confirming that CFE with `time.component.from = "nevertreated"` and no additional structure is numerically equivalent to gsynth. Model 3, which adds unnecessary linear trends, should produce similar or slightly worse MSPE because the extra parameters add noise without benefit when the true DGP has no unit-specific trends.

------------------------------------------------------------------------

## Additional Notes

Expand All @@ -507,3 +506,20 @@ Since `sim_gsynth` follows a pure IFE data generating process with two factors,
2. **Adding Covariates**: Including covariates in the model will significantly slow down the algorithm, as the IFE/MC model requires more time to converge. Users should be aware of this trade-off when incorporating covariates.

3. **Setting `min.T0`**: Setting `min.T0` to a positive value helps. The algorithm will automatically exclude treated units with too few pre-treatment periods. A larger $T_0$ reduces bias in causal estimates and minimizes the risk of severe extrapolation. When running cross-validation to select the number of factors, `min.T0` must be equal to or greater than (`r.max` + 2). Errors frequently occur when there are too few pre-treatment periods, so ensuring adequate $T_0$ (e.g. setting `min.T0 = 5`) is crucial.


## How to Cite

If you find this method helpful, you can cite @Xu2017.

```bibtex
@article{Xu2017,
title = {Generalized Synthetic Control Method: Causal Inference with Interactive Fixed Effects Models},
author = {Xu, Yiqing},
journal = {Political Analysis},
volume = {25},
number = {1},
pages = {57--76},
year = {2017}
}
```
22 changes: 17 additions & 5 deletions vignettes/08-panel.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ editor:
source("_common.R")
```

This chapter, authored by Ziyi Liu and Yiqing Xu, complements @CLLX2025 ([paper](https://yiqingxu.org/papers/english/2023_panel/CLLX.pdf), [slides](https://yiqingxu.org/papers/english/2023_panel/CLLX_slides.pdf)).
This chapter, authored by Ziyi Liu and Yiqing Xu, complements @CLLX2026 ([paper](https://yiqingxu.org/papers/english/2023_panel/CLLX.pdf), [slides](https://yiqingxu.org/papers/english/2023_panel/CLLX_slides.pdf)).
Rivka Lipkovitz also contributes to this tutorial. R script used in this chapter can be downloaded [here](https://raw.githubusercontent.com/xuyiqing/fect/dev/vignettes/rscript/08-panel.R).

------------------------------------------------------------------------

In recent years, researchers have proposed various heterogeneous treatment effect (HTE) robust estimators for causal panel analysis under parallel trends (PT) as alternatives to traditional two-way fixed effects (TWFE) models.
Examples include those proposed by @CDLZ, @sun2021-event, @callaway2021-did, @CDH2020, @IKW2023, @BJS2024, and @LWX2022.
Examples include those proposed by @CDLZ, @sun2021-event, @callaway2021-did, @CDH2020, @IKW2023, @BJS2024, and @LWX2024.
These methods are closely connected to the classic difference-in-differences (DID) estimator.

This chapter will guide you through implementing these HTE-robust estimators, as well as TWFE, in R.
Expand Down Expand Up @@ -596,7 +596,7 @@ fect.output <- as.matrix(out.fect$est.att)
head(fect.output)
```

@BJS2024 also provide the **didimputation** package to estimate the ATT using the same approach as @LWX2022.
@BJS2024 also provide the **didimputation** package to estimate the ATT using the same approach as @LWX2024.

```{r hh_impute, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 4.5, cache=TRUE}
df.impute <- df.use
Expand Down Expand Up @@ -835,7 +835,7 @@ p.pm

### Imputation Method

Now we return to the imputation method proposed by @BJS2024 and @LWX2022.
Now we return to the imputation method proposed by @BJS2024 and @LWX2024.
The estimated ATT is 0.127, with a standard error of 0.025.
Both are very close to the TWFE estimates.

Expand Down Expand Up @@ -976,4 +976,16 @@ esplot(data = res_st, main = "Stacked DID", xlim = c(-12,10))
## How to Cite

Please cite the authors of the original papers for their innovations.
If you find this tutorial helpful, you can cite @CLLX2025.
If you find this tutorial helpful, you can cite @CLLX2026.

```bibtex
@article{CLLX2026,
title={Causal Panel Analysis under Parallel Trends: Lessons from A Large Reanalysis Study},
author={Chiu, Albert and Lan, Xingchen and Liu, Ziyi and Xu, Yiqing},
journal={American Political Science Review},
volume={120},
number={1},
pages={245--266},
year={2026}
}
```
24 changes: 23 additions & 1 deletion vignettes/09-sens.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,26 @@ In this figure, different lines/bands will represent the robust CIs for $M=0$ (s

## How to Cite

Please cite @rambachan2023more for their original contribution to the sensitivity analysis framework for causal panel analysis. If you find this tutorial helpful, you can cite @CLLX2025.
Please cite @rambachan2023more for the original contribution on sensitivity analysis in causal panel analysis, and @CLLX2026 for adapting it to the counterfactual estimator framework.

```bibtex
@article{rambachan2023more,
title={A more credible approach to parallel trends},
author={Rambachan, Ashesh and Roth, Jonathan},
journal={Review of Economic Studies},
volume={90},
number={5},
pages={2555--2591},
year={2023}
}

@article{CLLX2026,
title={Causal Panel Analysis under Parallel Trends: Lessons from A Large Reanalysis Study},
author={Chiu, Albert and Lan, Xingchen and Liu, Ziyi and Xu, Yiqing},
journal={American Political Science Review},
volume={120},
number={1},
pages={245--266},
year={2026}
}
```
2 changes: 2 additions & 0 deletions vignettes/bb-updates.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## v2.2.0

(2026-03-27) CRAN release.

* Added `time.component.from` parameter: `"notyettreated"` (default) or `"nevertreated"` controls which units provide the time-varying model components (time fixed effects, latent factors, and temporal dynamics). Replaces `method = "gsynth"` with `method = "ife", time.component.from = "nevertreated"`.
* CFE estimator now supports `time.component.from = "nevertreated"`, enabling full CFE model components (additional FEs, $Z/\gamma$, $Q/\kappa$, latent factors) with never-treated estimation.
* Added `fect_mspe()` for out-of-sample model comparison (MSPE, RMSE, MAD) across specifications.
Expand Down
31 changes: 26 additions & 5 deletions vignettes/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ This Quarto book serves as a user manual for the **fect** package in R, which im

- @Xu2017 for Gsynth \[<a href="https://www.cambridge.org/core/journals/political-analysis/article/generalized-synthetic-control-method-causal-inference-with-interactive-fixed-effects-models/B63A8BD7C239DD4141C67DA10CD0E4F3" target="_blank">Paper</a>\]

- @LWX2022 for counterfactual estimators \[<a href="https://onlinelibrary.wiley.com/doi/full/10.1111/ajps.12723" target="_blank">Paper</a>\]
- @LWX2024 for counterfactual estimators \[<a href="https://onlinelibrary.wiley.com/doi/full/10.1111/ajps.12723" target="_blank">Paper</a>\]

- @CLLX2025 for a survey of the new DID estimators \[<a href="https://www.cambridge.org/core/journals/american-political-science-review/article/causal-panel-analysis-under-parallel-trends-lessons-from-a-large-reanalysis-study/219275E0CE901F099F2CFFBA07079243" target="_blank">Paper</a>\]
- @CLLX2026 for a survey of the new DID estimators \[<a href="https://www.cambridge.org/core/journals/american-political-science-review/article/causal-panel-analysis-under-parallel-trends-lessons-from-a-large-reanalysis-study/219275E0CE901F099F2CFFBA07079243" target="_blank">Paper</a>\]

::: {.callout-note appearance="simple"}
### Source Code
Expand All @@ -31,7 +31,7 @@ However, these counterfactual estimators come with important limitations:
- They generally do not accommodate dynamic treatment assignment given past outcomes or covariates---i.e., "feedback"---based on sequential ignorability.\
- Methods for continuous treatments are still underdeveloped and are not currently covered by **fect**.

@CLLX2025 reanalyze 49 published studies in political science and offer justifications for adopting these estimators.
@CLLX2026 reanalyze 49 published studies in political science and offer justifications for adopting these estimators.

## Why the Merge?

Expand Down Expand Up @@ -122,9 +122,27 @@ The following individuals (and AI) have contributed to **gsynth** and **fect**,
- [Rivka Lipkovitz](https://rivka.me/) (Undergraduate at MIT)
- [StatsClaw](https://github.com/xuyiqing/StatsClaw) (Agentic System for Statistical Software Development)



## How to Cite

To cite the **fect** package or this user manual, please use:

> Xu, Yiqing, Licheng Liu, Ye Wang, Ziyi Liu, Shijian Liu, Tianzhu Qin, Jinwen Wu, and Rivka Lipkovitz. 2026. *fect: Fixed Effects Counterfactual Estimators --- User Manual (v2.2.0).* <https://yiqingxu.org/packages/fect/>

```bibtex
@manual{fect2026,
title = {fect: Fixed Effects Counterfactual Estimators --- User Manual},
author = {Xu, Yiqing and Liu, Licheng and Wang, Ye and Liu, Ziyi and Liu, Shijian and Qin, Tianzhu and Wu, Jinwen and Lipkovitz, Rivka},
year = {2026},
note = {R package version 2.2.0},
url = {https://yiqingxu.org/packages/fect/}
}
```

## Report Bugs

Please report any bugs by submitting an issue on [GitHub](https://github.com/xuyiqing/fect/issues) or emailing me (yiqingxu \[at\] stanford.edu). We'd really appreciate it if you can include your minimally replicable code & data file and a **panelView** treatment status plot. Your feedback is highly valued!
Please report any bugs by submitting an issue on [GitHub](https://github.com/xuyiqing/fect/issues) or emailing me (yiqingxu \[at\] stanford.edu). We'd really appreciate it if you can include your minimally replicable code & data file and a [**panelView**](https://yiqingxu.org/packages/panelview/) treatment status plot. Your feedback is highly valued!

<!-- badges: start -->

Expand All @@ -136,6 +154,9 @@ Please report any bugs by submitting an issue on [GitHub](https://github.com/xuy
-->
```

**gsynth** (retiring): [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [<img src="https://www.r-pkg.org/badges/version/gsynth" alt="CRAN status"/>](https://CRAN.R-project.org/package=gsynth) [<img src="https://cranlogs.r-pkg.org/badges/grand-total/gsynth" alt="downloads: CRAN"/>](https://cran.r-project.org/web/packages/gsynth/index.html)
**gsynth** (wrapper): [![Lifecycle: stable](https://lifecycle.r-lib.org/articles/figures/lifecycle-stable.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [<img src="https://www.r-pkg.org/badges/version/gsynth" alt="CRAN status"/>](https://CRAN.R-project.org/package=gsynth) [<img src="https://cranlogs.r-pkg.org/badges/grand-total/gsynth" alt="downloads: CRAN"/>](https://cran.r-project.org/web/packages/gsynth/index.html)

**panelView**:
[![Lifecycle: stable](https://lifecycle.r-lib.org/articles/figures/lifecycle-stable.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [<img src="https://www.r-pkg.org/badges/version/panelView" alt="CRAN status"/>](https://CRAN.R-project.org/package=panelView) [<img src="https://cranlogs.r-pkg.org/badges/grand-total/panelView" alt="downloads: CRAN"/>](https://cran.r-project.org/package=panelView)

<!-- badges: end -->
4 changes: 2 additions & 2 deletions vignettes/references.bib
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@article{CLLX2025,
@article{CLLX2026,
title={Causal Panel Analysis under Parallel Trends: Lessons from A Large Reanalysis Study},
author={Chiu, Albert and Lan, Xingchen and Liu, Ziyi and Xu, Yiqing},
journal={American Political Science Review},
Expand All @@ -15,7 +15,7 @@ @article{li2025benchmarking
publisher={OSF}
}

@ARTICLE{LWX2022,
@ARTICLE{LWX2024,
title = "A Practical Guide to Counterfactual Estimators for Causal Inference with Time-Series Cross-Sectional Data",
author = "Liu, Licheng and Wang, Ye and Xu, Yiqing",
journal = "American Journal of Political Science",
Expand Down
13 changes: 0 additions & 13 deletions vignettes/vignettes.Rproj

This file was deleted.

Loading