Version 1.5.0 of {fetwfe} just hit CRAN. This is the first time I’ve posted about the package since the 0.4.4 blog announcement back in February, although I quietly shipped 1.0.0 to CRAN in May (and many incremental versions on GitHub as well). There have been lots of changes since 0.4.4, and I’ll outline them in this post.
Install or upgrade
To get the stable CRAN release:
install.packages("fetwfe")
You can always get the development branch as well, which updates more frequently:
# install.packages("remotes") # if needed
remotes::install_github("gregfaletto/fetwfePackage")
Headline features in 1.5.0
I’ll unpack each bullet in its own subsection, but here’s the overview:
- More estimators: I added implementations of extended TWFE (
etwfe()) as well as a bridge-penalized version of ETWFE (betwfe()). - S3 class + methods –
print()andsummary()play nicely withfetwfeobjects. - Simulation pipeline: a series of functions that can be piped together to simulate one panel data set (or many), run the supported methodologies on them, and extract the true treatment effects for evaluation.
- Regularization polish: optional argument
add_ridgethat adds a small amount of ridge regularization to stabilize estimation, or enableetwfe()for rank-deficient matrices. - Convenience functions for porting data sets that are already formatted for other packages, like
didoretwfe.
S3 makes results friendlier
Pre-1.5.0, fetwfe() spat out a bare list. Now it returns an object of class "fetwfe", complete with print() and summary() methods. Check it out yourself by running some code or looking at the displays in the getting started vignette (or just look at the featured image for this post).
Simulation workflow
I added functionality to simulate data sets in the way I did for the simulation studies in the paper. Now you can do simulations like this:
library(fetwfe)
# Simulate a random set of coefficients according
# to specified parameters
coefs <- genCoefs(R = 3, T = 5, d = 2, density = 0.1)
# Simulate a panel data set of 100 units over
# 5 time periods with 3 treated cohorts and
# 2 pre-treatment covariates. Then use fused
# extended two-way fixed effects to estimate
# the treatment effects.
truth_vs_est <- coefs |>
simulateData(N = 100) |>
fetwfeWithSimulatedData()
# Estimator output
summary(truth_vs_est)
# Ground truth average treatment effect on
# the treated units (ATT)
getTes(coefs)$att_true
The simulations vignette shows more details. All of the methods have ...WithSimulatedData() wrappers for convenience.
Regularization & numerics
I added an argument add_ridge to fetwfe() that adds a small amount of ridge regularization to the estimation, kind of like the elastic net (though it works with any choice of q, not just q = 1 like the elastic net). Although FETWFE is a regularized method, if the dimensionality gets high it might help to add a little regularization directly to the parameters themselves, since most of the FETWFE penalties just penalize coefficients towards other coefficients. I describe more about the motivation and implementation in Appendix J.1 (😅) of the most recent version of the paper as of this writing.
Convenience functions for porting from other R packages
Finally, for your convenience if you’re trying different packages for estimating difference-in-differences under staggered adoptions, I added two functions:
attgtToFetwfeDf(), which takes a data set formatted foratt_gt()from the{did}package and converts it to the format needed for the functions in the{fetwfe}package.etwfeToFetwfeDf(), which does the same for data sets formatted for theetwfe::etwfe()function from the{etwfe}package.
Feedback
As always, feel free to open or upvote an issue at github.com/gregfaletto/fetwfePackage/issues if you have any questions, concerns, or requests for the package. You can also reach out to me directly.
![A screenshot of R console output showing code to generate and summarize simulated panel data with “Fused Extended Two-Way Fixed Effects.” The summary reports an overall average treatment effect (ATT = –0.0414, SE = 0.1725, 95 % CI [–0.3796, 0.2968]), a table of cohort-specific treatment effects for cohorts 2–6 with estimates, standard errors, and confidence bounds, model metadata (120 units, 30 time periods, 5 treated cohorts, 12 covariates, 2,209 features, selected size = 179, lambda = 0.0232), and the true ATT value (–0.08828411).](https://gregoryfaletto.com/wp-content/uploads/2025/07/Screenshot-2025-07-03-at-12.05.53 PM.png)