Changelog

v1.5.0

Development version, not yet on CRAN.

Catch-up release for fect v2.4.x. Requires fect (>= 2.4.7).

Changes that affect results

  • Cross-validation of r: one number for r with CV = TRUE (the default) now searches r to 5, as documented and as in v1.2.1, so default calls give different results than in v1.3.1 to v1.4.0. Pass CV = FALSE to keep a fixed r.
  • Reproducible cross-validation: cross-validation holds out randomly chosen units and periods, so the chosen number of factors can differ from run to run; pass seed to make the choice reproducible.
  • weight now weights only the averaged effects, as documented and as in v1.2.1; W.est weights the model fit. Estimates change only when some control observations are missing.
  • Implied weights: with fect 2.4.7, wgt.implied uses the formula from Xu (2017), so the weighted control outcomes rebuild the factor part of each treated unit’s counterfactual. Rows and columns are named by unit id.
  • effect() returns the cumulative effect as the running sum of the per-period effects (from fect 2.4.7). Before, it was k times the average effect over periods 1 to k, which differs when the number of treated units changes over time.
  • IFE with never-treated controls: with fect 2.4.7, estimator = "ife" with time.component.from = "nevertreated", CV = FALSE and se = TRUE gives the never-treated estimate and standard errors, the same as estimator = "gsynth". Before, asking for standard errors silently switched to the not-yet-treated model.
  • effect() intervals: with fect 2.4.7, parametric fits (the default) and jackknife fits get intervals and p-values from normal critical values, as fit$est.att does. Before, t critical values made the intervals slightly wider (0.6% for a parametric fit at the default nboots = 200).
  • Jackknife standard errors: with fect 2.4.7, effect() uses the same jackknife formula as fit$est.att. Before, its standard errors were too large by the factor sqrt(N/(N - 1)) for N units (1% with 50 units), and fect’s att.cumu() gave a cumulative standard error about sqrt(N - 1) times too small.
  • effect() with weights: with fect 2.4.7, effect() on fits with weight (or W.agg) uses those weights in the estimates and standard errors, so its per-period effects equal fit$att. Before, it used equal weights.
  • ci.method = "basic" p-values: with fect 2.4.7, parametric fits (the default) get valid p-values for the effects, which agree with the basic intervals. Before, they were near 1 whatever the estimate.
  • Nonparametric ci.method = "basic" p-values: with fect 2.4.7, they agree with the basic intervals: a p-value is below alpha exactly when the interval excludes zero. Before, they came from the percentile rule, which can disagree with the interval.
  • fect_mspe() on gsynth fits: with fect 2.4.7, fect::fect_mspe() refits a gsynth fit with gsynth(), so it scores the fit’s own model, and it scores the model’s full prediction at each held-out cell. Before, it refitted fect’s default fixed-effects model, and its prediction left out part of the model, so the scores were far too large.
  • att.avg.unit: with fect 2.4.7, each treated unit’s average effect is taken over its observed cells under treatment. Before, a treated unit with any missing observation was left out, and the result was NaN when every treated unit had one.
  • normalize = TRUE: with fect 2.4.7, Y.dat is on the outcome’s scale, and so are the counterfactual plot, fect::imputed_outcomes() and the APTT and log ATT of fect::estimand(). Before, Y.dat stayed divided by the standard deviation of the outcome. The estimated effects do not change.
  • att.cumu() first row: with fect 2.4.7, the first row of fect::att.cumu() follows the rule of its other rows, so it equals the first row of effect(). The interval of nonparametric fits changes; parametric fits (the default) do not.

Bug fixes

  • effect() intervals come from the inference stored on the fit (with fect 2.4.7). Before, a fit with the default parametric inference gave intervals centered near zero.
  • The stored call is the call as typed, so print() shows it and update() works when inference was given.
  • plot(type = "raw") and plot(type = "missing") work after a Y =/D = call or with a formula stored in a variable, use id, and return the plot instead of drawing it.
  • plot(type = "raw") and plot(type = "missing") stop with a message that names an id that is not a unit of the data.
  • inference = "parametric" with estimator = "ife"/"mc" or EM = TRUE stops with a message in gsynth’s own argument names.
  • inference = "jackknife" with ci.method = "basic" stops with a message in gsynth’s own argument names; only ci.method = "normal" works with the jackknife.
  • print() returns the fit invisibly.
  • With fect 2.4.7, a jackknife fit with weight and placeboTest = TRUE works when the model has covariates, and its est.placebo has the 90% interval.
  • With fect 2.4.7, fect::estimand() on a jackknife fit uses ci.method = "normal" by default for every type. Before, "att.cumu", "aptt" and "log.att" stopped unless it was given.
  • With fect 2.4.7, fect::estimand(fit, "att.cumu", "overall", window = c(k, k)) works for a one-period window.
  • With fect 2.4.7, fect::estimand(fit, "att.cumu", cells = ...) stops and points to window. Before, cells was ignored.

New features and other changes

  • Gap plot of chosen units: with fect 2.4.7, plot(fit, type = "gap", id = ...) again draws the chosen treated unit’s own gap by time relative to its treatment start, as in v1.2.1, and with several ids their unweighted average. With parametric inference (the default), it adds a band from the units’ bootstrap draws; with the nonparametric bootstrap or the jackknife, it shows point estimates only. One unit’s gap in one period is a noisy estimate of its effect, which is not identified. A control unit, or an id not in the data, stops with a message naming it. See Chapter 3  Plot customization.
  • Diagnostics: placebo test (placeboTest = TRUE, placebo.period) and loading-overlap plot (plot(fit, type = "loading.overlap")). See Chapter 1  Gsynth.
  • Inference: new ci.method argument: "normal" (default; Wald) or "basic" (reflected-pivot bootstrap, Davison and Hinkley (1997)). "basic" works with parametric and nonparametric inference, not with the jackknife.
  • Plot recipe: modern visual style from fect v2.3.x, with new arguments legacy.style, highlight, highlight.fill. See Chapter 3  Plot customization.
  • Weights: new W.est (weights for the model fit) and W.agg (weights for the averaged effects), from fect 2.3.1. weight is the same as W.agg.
  • CV defaults: rolling-window (cv.method = "rolling", cv.prop = 0.1, cv.buffer = 1); default k is now 20.
  • CV settings: new cv.rule ("1se" default, "min", "1pct") for choosing the number of factors, and cv.nobs and cv.donut for block cross-validation, all passed to fect. With estimator = "gsynth", cv.rule takes effect with fect 2.4.7 or later.
  • Soft-deprecated paths: estimator = "ife", estimator = "mc", EM = TRUE, and effect(). For these methods — and for post-hoc estimands (cumulative ATT, APTT, log-ATT) — use fect::fect() and fect::estimand() directly. Migration recipes in Chapter 2  IFE-EM & MC.
  • Guardrail: inference = "parametric" with estimator = "ife" or "mc" now errors instead of falling back to nonparametric bootstrap with a warning.

v1.4.0

(2026-03-27) CRAN release.

  • Breaking change: estimator parameter now maps directly to estimation methods. estimator = "gsynth" (new default) uses Xu (2017); estimator = "ife" uses Gobillon and Magnac (2016) EM algorithm; estimator = "mc" uses Athey et al. (2021) matrix completion. The legacy EM = TRUE parameter is equivalent to estimator = "ife".
  • Fixed loadings plot warnings (upstream fix in fect).
  • Replaced pkgdown vignette with Quarto book tutorial.

v1.3.1

(2025-12-07)

  • Updated DESCRIPTION and documentation.

v1.3.0

Merged all functionalities of gsynth into fect. gsynth is now a wrapper of fect. See the fect User Manual for updates.

v1.1.7

Normal approximation for confidence intervals based on bootstrapped standard errors (replacing the percentile method).

v1.1.4

  1. Import felm from lfe for two-way FE starting values with unbalanced panels.
  2. Add cluster bootstrap option.
  3. Add jackknife uncertainty estimates.
  4. Add cumuEff function for sub-group and cumulative treatment effects.

v1.0.9

  1. panelView() removed from gsynth and released as an independent package.
  2. Implement matrix completion method.
  3. Bug fixes and color scheme changes.

v1.0.8

  1. Add panelView() for data visualization.
  2. Bug fixes.

v1.0.7

  1. Add implied weights (wgt.implied) to output.
  2. Add missing data / treatment status plot (type = "missing").
  3. Accommodate unbalanced panels.