Changelog
Source:NEWS.md
fixes 0.11.2 (2026-06-11)
Bug fixes (silent-corruption class)
CS estimator: character / factor unit IDs produced silently wrong results (
run_es(estimator = "cs")andcalc_att(estimator = "cs")): unit IDs were coerced withas.integer(), which turns every character ID intoNA— all units collapsed into one inside the Rcpp kernel and the ATT(g,t) table was meaningless, with no error raised. Unit IDs are now densely re-encoded withmatch(); character, factor, and arbitrary numeric IDs give results identical to integer IDs.CS estimator: a cohort with
timing == 0leaked into the control group:0Lwas the internal never-treated sentinel, so a genuine cohort first treated at time 0 (e.g., event-time-centred data) was silently used as never-treated controls.time/timingare now shifted by a common internal offset so the sentinel can never collide; results are invariant to common shifts of the time axis.Classic staggered TWFE dropped the entire never-treated control group (
estimator = "twfe",staggered = TRUE): the relative-time variable isNAfor never-treated units andfixest::feols()removes rows with NA regressors, so every control row was excluded from the estimation sample (visible only as a fixest NOTE). Those rows are now assigned the (excluded) baseline level — their event dummies are identically zero because thei()interaction is multiplied bytreatment = 0— so the control group is correctly retained.N_treated/N_nevertreatedmetadata still reflect the original NA pattern.method = "sunab"dropped the entire never-treated control group:fixest::sunab()has no NA-cohort convention and drops those rows. Never-treated units are now recoded internally to a cohort far beyond the sample period (thefixest::base_staggconvention) and retained as controls. Verified numerically identical to a directfixest::feols(y ~ sunab(...))call using the same recoding.Rcpp (unit, time) lookup key: replaced the multiplicative hash (which could collide for time values above 1,000,003, e.g. Unix timestamps) with a collision-free 64-bit
(unit << 32) | timekey insrc/compute_att_gt.cpp.
Improved input validation
- CS: clear, actionable error when the time grid does not advance in steps of 1 (the
g - 1base-period assumption), instead of the generic “No ATT(g,t) estimates were computed”. - CS: warning that names cohorts skipped because their base period (
g - 1 - anticipation) is not observed. - CS / SA / TWM / FLEX: fractional
time/timingvalues now raise an error instead of being silently truncated byas.integer()(new shared helper.assert_integerish()). - SA / TWM / FLEX: warning when the requested
baselinereference period is not feasible for any cohort, in which case no period would be excluded and the regression is unnormalised.
Performance
- Verified on a 400,000-row staggered panel (20,000 units × 20 periods): every estimator completes in roughly 1–3 s (CS bootstrap with B = 999 ≈ 3 s), peak memory ≈ 1.3 GB.
- BJS: singleton-unit FE recovery vectorised (was O(#singletons × N), which could take minutes on large unbalanced panels).
- CS: event-study aggregation and bootstrap influence-function bookkeeping vectorised (
match()on keys instead of per-cohort scans).
fixes 0.11.1 (2026-05-30)
Improvements
run_es()— diagnostic warning for ambiguoustiming = NA(classic TWFE,staggered = TRUEonly): awarning()is now emitted when any unit hastreatment = 1in at least one row buttiming = NA. Such units are silently absorbed as never-treated controls — correct whenNAis intentional, but dangerous whenNArepresents genuinely missing treatment timing. The warning names up to 5 affected unit IDs (whenunitis supplied) for quick diagnosis.@param timingdocumentation clarified: all staggered estimators (cs, sa, bjs, twm, flex, classic withstaggered = TRUE) share the sameNA = never treatedconvention asdid::att_gt()andfixest::sunab(). The roxygen documentation now states this explicitly and notes the risk of silent misclassification whenNArepresents missing data rather than “never treated”.
fixes 0.11.0 (2026-05-24)
New Features
-
honest_sensitivity()— honest robust inference (Rambachan & Roth 2023) (R/honest_did.R): sensitivity analysis for event-study / DiD designs when parallel trends may be violated. Instead of assuming parallel trends holds exactly, it reports confidence sets for a post-treatment effect under progressively weaker restrictions on the difference in trends, and a breakdown value (the largest restriction at which the effect is still significant):res <- run_es(df, outcome = y, treatment = treat, time = year, timing = 6, fe = ~ id + year) h <- honest_sensitivity(res, type = "relative_magnitude", Mvec = c(0, 0.5, 1, 1.5, 2)) plot_honest(h)- Restriction families:
"relative_magnitude"() and"smoothness"(). - Inference via the Andrews-Roth-Pakes (ARP) conditional moment-inequality test — a pure-R reimplementation (no dependency on the HonestDiD package).
- Works directly from a
run_es()es_result(estimator"twfe": classic ormethod = "sunab", which now carry the event-study coefficient covariance via the newes_vcovattribute), or from a rawbetahat/sigmapair for any estimator. -
plot_honest()/autoplot()draw the “top-down” sensitivity plot;print.honest_result()reports the breakdown value. - Validated against the HonestDiD reference package (method
"Conditional"): (single post period) matches to machine precision; matches to grid resolution. Heavy numeric helpers (lpSolveAPI,Rglpk,TruncatedNormal,Matrix,pracma) are inSuggestsand gated withrequireNamespace().
- Restriction families:
Internal / Refactor
Estimator-core consolidation (behaviour-preserving): factored the boilerplate duplicated across
run_es(),calc_att(),run_did(), and the five estimator backends into shared helpers in R/utils-internal.R —.resolve_col()(NSE column resolution),.add_ci_columns()(CI construction),.validate_panel_cols(),.compute_cohort_sizes(),.model_vcov_full(), and.aggregate_iw(). Thecalc_att()aggregation loops were vectorised. All existing tests pass unchanged.-
run_did()— basic TWFE DiD estimator (R/run_did.R): New function for classic two-way fixed-effects difference-in-differences. Accepts a pre-built binary treatment indicatorD_itand returns adid_resultS3 object with fullmodelsummary/tinytablecompatibility:df$D <- as.integer(df$treated & df$year >= 2006) result <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) print(result) modelsummary::modelsummary(result) # tinytable output (modelsummary >= 2.0)- NSE API consistent with
run_es()andcalc_att()— specify variables by name, not by formula construction. -
feauto-inferred as~ unit + timewhen bothunitandtimeare supplied andfe = NULL. -
tidy.did_result()delegates tobroom::tidy.fixest()for full regression table (all regressors);glance.did_result()delegates tobroom::glance.fixest()for model-level stats (within.r.squared,nobs,AIC, etc.). -
print.did_result()shows a clean header: estimator, sample sizes, FE spec, VCOV type. - Outcome expressions like
log(y)supported. -
modelsummaryandtinytableadded to Suggests.
- NSE API consistent with
-
calc_att()— ATT aggregation function (R/calc_att.R): New function that separates “calculating ATT” from “running an event study”. Whilerun_es()produces a full dynamic event-study curve (effects by relative time),calc_att()yields aggregated ATT estimates with a clear, minimal interface:calc_att(data, outcome = y, time = year, timing = g, unit = id, estimator = "cs", aggregation = "simple") # overall ATT calc_att(..., aggregation = "by_cohort") # ATT per cohort calc_att(..., aggregation = "by_time") # ATT per calendar period-
Estimators:
"cs"(Callaway-Sant’Anna 2021) and"bjs"(Borusyak et al. 2024). SA, TWM, FLEX are event-study-only estimators and are not supported (userun_es()). -
Aggregation formulas (CS) match
did::aggte()for point estimates:-
"simple": exposure-weighted average over all post-treatment (g,t) pairs. -
"by_cohort": mean ATT(g,t) over post-treatment periods per cohort. -
"by_time": cohort-size-weighted ATT per calendar period.
-
-
SEs: independence assumption (diagonal delta-method). Systematically smaller than
did::aggteSEs, which use influence-function variance accounting for within-cohort time correlation. Cluster-robust SE for BJS aggregations planned for v0.12. -
Returns an
att_resultS3 object (data.frame subclass) with columnsgroup,estimate,std.error,statistic,p.value,conf_low_XX/conf_high_XX. Attributes:aggregation,estimator,N,N_units,N_treated,control_group(CS only),att_gt(raw CS ATT(g,t) table),tau_it(BJS unit-time effects table). -
print.att_result()S3 method provides a concise summary.
-
Estimators:
Testing
-
48 new tests in
tests/testthat/test-att.R:- Return type and column contract for all aggregation types
- CS point estimates match
did::aggte()at tolerance 1e-4 - BJS estimates match manual
mean(tau_it$tau_hat)at tolerance 1e-12 - Multiple
conf.levelsupport verified
fixes 0.10.1 (2026-05-14)
Internal
-
run_es.Rrefactoring: Extracted.make_tidy()and.es_finalize()private helpers that centralise the repeated tidy-construction / baseline-row / range-filter / attr-stamping pattern that was previously duplicated across thecs,sa,bjs,twm, andflexbranches (~360 lines removed). No API change; all 593 tests pass. -
profvis benchmark harness: Added
inst/profile/benchmark.Rwithprofile_estimator()andbenchmark_all()utilities. Run interactively to generate flamegraph HTML and wall-clock summary across estimators before starting Phase 3 Rcpp work. -
CLAUDE.md documentation: Added
src/compute_att_gt.cpp(shipped in v0.8.1 but missing from the Rcpp Acceleration Roadmap), and updated Package Structure to list all 13 R source files, 5 Rcpp files, and 16 test files that now exist. -
Edge-case tests (19 new, 593 total):
-
test-twm.RTest 16 —trends=TRUEwith exactly 2 pre-treatment periods succeeds without warning (boundary condition of the ≥ 2 requirement). -
test-twm.RTest 17 — explicitlead_range/lag_rangecorrectly trims TWM output and preserves estimates in the shared window (exercises.es_finalize()filter). -
test-flex.RTest 12 — explicitlead_range/lag_rangetrims FLEX output correctly. -
test-flex.RTest 13 — FLEX succeeds with an all-treated panel (no never-treated groups;N_nevertreated == 0). -
test-sa.R— explicitlead_range/lag_rangetrims SA output and preserves estimates within the shared window.
-
fixes 0.10.0 (2026-05-14)
New Features
-
run_es(estimator = "twm", trends = TRUE): Cohort-specific linear trend detrending (Wooldridge 2025, Section 8). Addsd_g * tregressors so each cohort’s counterfactual trend can deviate linearly from the common time trend. Implemented as post-treatment-only cells + trend columns; requires >= 2 pre-treatment periods per cohort. Output showsrelative_time >= 0only (pre-trend testing is deferred to the no-trend model). -
run_es(estimator = "twm", covariates = ~ x1 + x2): Full Wooldridge (2025) Procedure 5.1 covariate interactions. Adds treatment-cell × cohort-demeaned covariate terms (ẋ_{ig} = x_i - x̄_g) andi(time, x_j)conditional parallel-trends controls (Eqs. 5.2-5.3). -
run_es(estimator = "flex", covariates = ~ x1 + x2): Full Deb et al. (2024) Eq. 3.1 covariate interactions for RCS data. Cell-level centeringX_{i,t} - X̄_{g,t}(Eq. 2.11) withi(time, x_j)andi(group, x_j)conditional PT controls.
Performance (Rcpp Phase 2)
-
src/indicator_matrix.cpp—build_indicator_matrix_cpp(): Replaces the pure-R nested for-loop that fills the 0/1 indicator matrix in the SA, TWM, and FLEX estimators. Single shared Rcpp utility, O(N×K) integer fill with no R allocation overhead per column. -
src/iw_aggregation.cpp—aggregate_iw_cpp(): Replaces the R event-time aggregation loop and thet(w) %*% V_sub %*% wquadratic-form VCOV step in SA, TWM, and FLEX. Uses RcppArmadilloarma::mat::submat()for O(1) VCOV block extraction andarma::as_scalar(w.t() * V_sub * w)for the quadratic form. -
src/cov_demeaning.cpp—build_cov_interactions_cpp(): Replaces the pure-R covariate demeaning loops in TWM (cohort-level centering) and FLEX (group×time cell-level centering) with a singlestd::unordered_map-based O(N) grouping pass followed by column-wise mean subtraction, then builds the N × (K×p) treatment-cell × centred-covariate interaction matrix in C++. -
src/bootstrap_cs.cpp—bootstrap_cs_cpp(): Replaces the R-levelapply/sweepcalls in the CS multiplier bootstrap with RcppArmadillo DGEMM for both the pilot and main stages. UsesR::runif()for Mammen weight generation (column-major fill order matches R’smatrix()) so results are numerically identical to the pure-R path under the sameset.seed(). - Added
src/Makevarsandsrc/Makevars.winlinking$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)for cross-platform RcppArmadillo support. -
RcppArmadilloadded toLinkingToin DESCRIPTION.
fixes 0.9.0 (2026-05-14)
New Features
-
run_es(estimator = "twm"): Wooldridge (2025) Two-Way Mundlak (TWM) estimator for panel data. Implements Procedure 5.1 via POLS on cohort x calendar-time treatment cells with two-way FE. Algebraically identical toestimator = "sa"in the no-covariate base case (verified numerically at tolerance 1e-10). Thetrends = TRUEextension (cohort-specific linear trend detrending, Wooldridge 2025 Section 8) is reserved for v0.9.1. -
run_es(estimator = "flex", group = <group_id>): Deb, Norton, Wooldridge & Zabel (2024) FLEX estimator for repeated cross-section (RCS) data. Uses group x calendar-time OLS with group+time FE (no unit FE). Algebraically equivalent to the multi-step imputation estimator (Proposition 2.1). Newgroupargument identifies the treatment group (R_{ig}) each individual belongs to. Default clustering is by group. Covariate interactions deferred to v0.9.1. - Reference PDFs converted to TXT:
papers/Deb et al. (2024).txt,papers/Woodridge (2025).txt.
fixes 0.8.1 (2026-05-10)
CRAN release: 2026-05-10
New Features
-
run_es(estimator = "cs"): Callaway-Sant’Anna (2021) estimator. Computes group-time ATT(g,t) via the unconditional DiD estimand (eq. 2.8) with never-treated or not-yet-treated control groups. Supportscontrol_group = "nevertreated"(default) or"notyettreated". The full ATT(g,t) matrix is stored as theatt_gtattribute of the result. -
run_es(estimator = "sa"): Sun-Abraham (2021) interaction-weighted estimator. Aggregates cohort x relative-time interactions by cohort share weights. Numerically identical tofixest::sunab()to machine precision. -
run_es(estimator = "bjs"): Borusyak, Jaravel & Spiess (2024) imputation estimator. Fits TWFE on untreated observations only, imputes counterfactuals for treated observations, and averages treatment effects by horizon. Handles singleton unit fixed effects via closed-form recovery. -
run_es(bootstrap = TRUE): Multiplier bootstrap for simultaneous confidence bands (Algorithm 1, Callaway & Sant’Anna 2021). Addsconf_low_sim/conf_high_simcolumns to the result and stores the (g,t)-level bootstrap object asattr(result, "bootstrap"). Controlled byB(draws, default 999) andboot_seedarguments. Available only whenestimator = "cs". -
plot_att_gt(): Visualize the full ATT(g,t) matrix from CS results as a heatmap (type = "heatmap") or cohort-faceted time series (type = "facet"). Requiresestimator = "cs"result as input. Whenbootstrap = TRUEwas used, the heatmap adds a subtitle with the simultaneous critical value and open-diamond markers for simultaneously significant cells; the facet adds a lighter simultaneous CI ribbon. -
plot_es(show_simultaneous = TRUE): Overlays the simultaneous bootstrap CI (lighter band, alpha 0.15) alongside the pointwise CI (alpha 0.3) with a two-entry legend. Errors informatively if bootstrap was not run. -
plot_es_interactive(show_simultaneous = TRUE): Adds a second lighter ribbon trace for the simultaneous CI and extends the hover tooltip with simultaneous CI bounds.
Bug Fixes
-
run_es()bootstrap path:base::merge()silently dropped all custom attributes (e.g.att_gt,N_units,lead_range) from thees_resultobject. Attributes are now saved and restored around the merge, soplot_att_gt()works correctly after abootstrap = TRUErun.
fixes 0.7.2 (2026-05-02)
CRAN release: 2026-05-02
Bug Fixes
-
Clustered standard errors no longer silently overridden by HC1:
- Fixed a bug where specifying
clusterinrun_es()did not produce clustered standard errors - The default
vcov = "HC1"was being applied after model estimation, overriding the clustered SE fromfeols() - Now, when
clusteris specified andvcovis left at its default ("HC1"), the model’s clustered standard errors are used - To explicitly request HC1 SEs even when
clusteris set, passvcov = "HC1"together withcluster = NULL - Applies to both
classicandsunabmethods - This resolves discrepancies between
run_es()results and equivalent directfixest::feols()calls
- Fixed a bug where specifying
fixes 0.7.1 (2025-11-02)
Bug Fixes
-
Lead/lag range filtering now enforced:
- Fixed bug where
lead_rangeandlag_rangeparameters were ignored, causing all estimated coefficients to be returned regardless of specified ranges - Results now correctly filtered to only include coefficients within
[-lead_range, lag_range] - Applies to both
classicandsunabmethods
- Fixed bug where
-
sunab() namespace error resolved:
- Fixed
'sunab' is not an exported object from 'namespace:fixest'error when usingmethod = "sunab" - Formula environment now correctly configured to access
sunabfunction from fixest package - sunab() calls now work identically to direct fixest::feols() usage
- Fixed
Enhancements
-
Baseline row now included in sunab results:
- The
baselineparameter (default: -1) now applies to bothclassicandsunabmethods - Baseline period added to results with
estimate = 0,std.error = 0, andis_baseline = TRUE - Provides consistent behavior across both estimation methods
- Updated documentation to clarify that
baselineis used for both methods
- The
-
Improved term column formatting:
- Term values now display as clean numeric strings (e.g.,
"-9","0","3") - Removed complex fixest-specific notation (e.g.,
"year::-9") for better readability - Consistent formatting across both classic and sunab methods
- Term values now display as clean numeric strings (e.g.,
-
Modernized code with native pipe operator:
- Replaced tidyverse pipe (
%>%) with base R pipe (|>) throughout the package - Requires R >= 4.1.0 (already enforced in DESCRIPTION)
- Cleaner code with no functional changes
- Replaced tidyverse pipe (
Testing
-
Comprehensive test suite overhaul:
- Added 25+ test cases covering all bug fixes and enhancements
- Separate test suites for classic, staggered, and sunab methods
- Tests for baseline row inclusion, term formatting, and range filtering
- Integration tests with fixest built-in datasets (base_did, base_stagg)
- Tests use native pipe operator (
|>)
fixes 0.7.0 (2025-11-01)
Bug Fixes
-
Critical fix for relative_time calculation in non-staggered designs:
- Fixed bug where
relative_timewas NA for all coefficients except baseline when using non-staggered treatment timing - The reference period in
fixest::i()now correctly corresponds to thebaselineparameter - For example, with
timing = 5andbaseline = -1, period 4 (not period 5) is now used as the reference - This ensures proper event study estimation with the intended baseline period
- Fixed bug where
New Features
-
Interactive plotting with plotly:
- New function
plot_es_interactive()for creating interactive event study plots - Hover tooltips display: relative time, point estimate, confidence intervals, standard error, and p-value
- Supports customizable confidence levels, colors, and styling options
- Optional ribbon or point-only display modes
- Fully compatible with
es_resultobjects fromrun_es()
- New function
Performance Improvements
-
Optimized relative_time extraction:
- Vectorized term parsing replaces previous
sapply()approach for significant performance gains - Faster processing of large event study results
- Vectorized term parsing replaces previous
-
Enhanced error reporting:
- More informative warnings when term parsing fails
- Better debugging information for malformed coefficient names
fixes 0.5.0 (2025-07-06)
CRAN release: 2025-07-07
New Features
-
Multiple Confidence Intervals:
run_es()andplot_es()now support returning and visualizing multiple confidence levels (e.g., 90%, 95%, 99%) in a single analysis. -
Enhanced Plotting Options:
plot_es()addsci_levelselection, more theme options (theme_style), and improved ribbon/error bar display. -
Expanded Error Handling:
More informative error reporting for all argument validation and model mis-specification. -
Documentation Overhaul:
Updated README, vignette, and roxygen docs to reflect all new features and usage patterns.
Improvements
-
Input Validation:
Stricter checks for all arguments and clearer, friendlier error messages. -
Staggered Timing:
More robust handling of partial or missing treatment timing. -
Code Refactoring:
Internal codebase cleaned for maintainability and reliability.
fixes 0.4.1 (2025-06-30)
CRAN release: 2025-06-30
New Features
-
Support for untreated units (
NAin timing):- Units with missing
timingare now retained as never-treated controls (staggered only).
- Units with missing
-
Flexible
weightsinput:- Accepts formulas (
~ popwt), bare names (popwt), or character strings ("popwt").
- Accepts formulas (
-
Improved
clusterinput handling:- Now supports formula, character vector, and bare names consistently.
Improvements
- Better validation and error messages across all inputs.
- Warning added if
unitis supplied withouttime_transform = TRUE. - Documentation switched to Markdown-style lists for better readability.
fixes 0.4.0 (May 25, 2025)
CRAN release: 2025-05-25
New Features
- Added support for staggered treatment timing:
- New
staggered = TRUEoption allowstimingto vary by unit (e.g., treatment year column). - Units with
NAintimingare safely retained as untreated.
- New
- Added support for observation weights:
- Use the
weightsargument (e.g.,~ popwt) to run weighted regressions.
- Use the
-
Automatic lead/lag range detection:
- If
lead_rangeorlag_rangeisNULL, the function computes the maximum feasible range from the data.
- If
fixes 0.3.1 (May 18, 2025)
Improvements
- Improved default x-axis scaling in
plot_es():- The x-axis now uses
ggplot2::scale_x_continuous()with integer breaks spaced by 1, aligned to therelative_timerange. - This provides more readable and consistent event time labeling in plots.
- The x-axis now uses
fixes 0.3.0 (May 18, 2025)
New Features
- Added support for irregular and non-numeric time variables such as
Date:- Introduced
time_transform = TRUEto automatically convert thetimevariable into a unit-level sequential index (1, 2, 3, …) for event study estimation. - Added
unitargument to specify the panel unit identifier required whentime_transform = TRUE. - This enables seamless analysis of panel data with monthly, quarterly, or irregular time formats.
- Introduced
Improvements
- Updated input validation:
- Now accepts
Dateclass in thetimevariable and converts it automatically to numeric iftime_transform = FALSE. - Improved error messages and warnings for better user feedback when
unitis missing ortimeis of unsupported type.
- Now accepts
- Enhanced documentation:
- Updated
@examplesin the function documentation to includeDate-based examples. - Extended vignette to illustrate
time_transformusage. - Expanded
README.mdto describe irregular time handling and demonstrate new use cases.
- Updated
- Strengthened test coverage:
- Added new unit tests for
time_transform,unithandling, andDateconversion edge cases.
- Added new unit tests for
fixes 0.2.1 (May 11, 2025)
CRAN release: 2025-05-10
Minor Improvements
- Added a warning when lead/lag dummy variable names (e.g.,
lead1,lag0) already exist in the dataset to prevent accidental overwriting. - Added a warning when filtered data (based on
lead_range,lag_range, andinterval) has fewer than 10 rows, helping users identify overly narrow estimation windows. - Improved handling of the
treatmentvariable: it is now coerced to logical usingas.logical()to support both binary numeric (0/1) and logical (TRUE/FALSE) formats. - Fixed internal bug in model formula construction:
- Previously, fixed effects specified via the
feargument (e.g.,~ id + year) were combined usingmodel_formula | fe_text, which caused evaluation errors during tests. - Now, the full model formula is safely constructed as a string and parsed with
as.formula()to ensure compatibility withfixest::feols().
- Previously, fixed effects specified via the
fixes 0.2.0 (March 29, 2025)
CRAN release: 2025-04-23
Major Features
-
Support for covariates in
run_es():- Covariates must now be specified as a one-sided formula (e.g.,
~ x1 + x2).
- Covariates must now be specified as a one-sided formula (e.g.,
-
Fixed Effects and Clustering Interface Updated:
-
feandclusterarguments must now be specified using a one-sided formula (e.g.,~ id + year). - Character vector input for
clusteris still accepted. - Improved internal handling and validation of fixed effects and clustering variables.
-
- Improved error messages for invalid or missing variable names.
fixes 0.1.0 (March 17, 2025)
CRAN release: 2025-03-18
Major Changes
-
fe_varargument now supports additive notation (firm_id + year) instead of character vectors. - Improved
plot_es()efficiency and documentation.
fixes 0.0.2 (Enhancements & Fixes)
This version introduced several enhancements and refinements to improve usability and maintainability.
Improvements
- Refactored variable name handling:
-
outcome_var,treated_var, andtime_varare now processed usingrlang::ensym()for better robustness. -
fe_varandcluster_varhandling improved for more reliable column referencing.
-
- More informative error messages when variables are missing in the dataset.
- Enhanced baseline term handling in regression models to prevent incorrect factor levels.
- Improved
plot_es()function:- Added validation checks to ensure required columns (
relative_time,estimate, etc.) are present. - Adjusted confidence interval calculations to avoid missing values in error bars.
- Added validation checks to ensure required columns (
fixes 0.0.1 (Initial Release)
This is the first release of the fixes package, providing tools for estimating and visualizing event study models with fixed effects.
Features
-
run_es(): A function to estimate event study models usingfixest::feols(), generating lead and lag variables automatically.- Supports fixed effects (
fe_varas character vector). - Allows clustered standard errors via
cluster_var. - Handles time scaling through the
intervalargument.
- Supports fixed effects (
-
plot_es(): A function to visualize event study results with ggplot2.- Supports ribbon-style confidence intervals (
type = "ribbon", default). - Allows error bar visualization (
type = "errorbar"). - Customizable plot elements including colors, line styles, and reference lines.
- Supports ribbon-style confidence intervals (
Initial Implementation
-
Fixed effects regression model using
fixest::feols(). - Automated creation of lead/lag dummy variables based on treatment timing.
- Baseline period exclusion to avoid multicollinearity.
-
Support for custom time intervals (
intervalargument).