The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Note
By default, thefixespackage assumes time is a regularly spaced numeric variable (e.g., year = 1995, 1996, …).
If your time variable is irregular or non-numeric (e.g.,Datetype), settime_transform = TRUEto automatically convert it to a sequential index within each unit.
For unit-specific treatment timing, setstaggered = TRUE.
The fixes package is designed for convenient event study
analysis and plotting, particularly useful for visualizing parallel
trends and dynamic effects in two-way fixed effects (TWFE)
difference-in-differences (DID) research.
Key Functions:
run_es() — Takes a data frame, generates lead/lag
dummies, and fits the event study regression. Supports fixed effects,
covariates, clustering, staggered timing, weights, custom baseline, and
multiple confidence intervals.plot_es() — Plots event study results using
ggplot2 with flexible options: ribbon or error bars, choice
of CI level, and theme customization.Install from CRAN:
install.packages("fixes")Or with pak:
pak::pak("fixes")For the latest development version from GitHub:
pak::pak("yo5uke/fixes")First, load the library.
library(fixes)run_es() expects a panel data frame with at least:
Date)For staggered adoption
(staggered = TRUE), include a variable specifying
unit-specific treatment timing (e.g., “treatment_year”).
Widely used panel datasets include:
did::sim_dt(): simulated panel for DiD tutorialsfixest::base_stagg: a built-in dataset for staggered
adoptiondf1 <- fixest::base_did # Basic DiD
df2 <- fixest::base_stagg # Staggered treatment| y | x1 | id | period | post | treat |
|---|---|---|---|---|---|
| 2.8753063 | 0.5365377 | 1 | 1 | 0 | 1 |
| 1.8606527 | -3.0431894 | 1 | 2 | 0 | 1 |
| 0.0941652 | 5.5768439 | 1 | 3 | 0 | 1 |
| 3.7814749 | -2.8300587 | 1 | 4 | 0 | 1 |
| -2.5581996 | -5.0443544 | 1 | 5 | 0 | 1 |
| 1.7287324 | -0.6363849 | 1 | 6 | 1 | 1 |
| id | year | year_treated | time_to_treatment | treated | treatment_effect_true | x1 | y | |
|---|---|---|---|---|---|---|---|---|
| 2 | 90 | 1 | 2 | -1 | 1 | 0 | -1.0947021 | 0.0172297 |
| 3 | 89 | 1 | 3 | -2 | 1 | 0 | -3.7100676 | -4.5808453 |
| 4 | 88 | 1 | 4 | -3 | 1 | 0 | 2.5274402 | 2.7381717 |
| 5 | 87 | 1 | 5 | -4 | 1 | 0 | -0.7204263 | -0.6510307 |
| 6 | 86 | 1 | 6 | -5 | 1 | 0 | -3.6711678 | -5.3338166 |
| 7 | 85 | 1 | 7 | -6 | 1 | 0 | -0.3152137 | 0.4956263 |
run_es()The main event study function. All key arguments below:
| Argument | Description |
|---|---|
data |
Data frame to be used. |
outcome |
Outcome variable. Can be specified as a raw variable or a
transformation (e.g., log(y)). Provide it unquoted. |
treatment |
Dummy variable indicating the treated units. Provide it unquoted.
Accepts both 0/1 and TRUE/FALSE. |
time |
Time variable. Provide it unquoted. |
timing |
The time at which the treatment occurs. If
staggered = FALSE, this should be a scalar (e.g.,
2005). If staggered = TRUE, provide a variable
(column) indicating the treatment time for each unit. |
fe |
Fixed effects to control for unobserved heterogeneity. Must
be a one-sided formula (e.g., ~ id + year). |
lead_range |
Number of pre-treatment periods to include (e.g., 3 =
lead3, lead2, lead1). Default is
NULL, which automatically uses the maximum available lead
range. |
lag_range |
Number of post-treatment periods to include (e.g., 2 =
lag0 (the treatment period), lag1,
lag2). Default is NULL, which automatically
uses the maximum available lag range. |
covariates |
Additional covariates to include in the regression. Must be
a one-sided formula (e.g., ~ x1 + x2). |
cluster |
Specifies clustering for standard errors. Can be a character
vector (e.g., c("id", "year")) or a
formula (e.g., ~ id + year,
~ id^year). |
weights |
Optional weights to be used in the regression. Provide as a
one-sided formula (e.g., ~ weight). |
baseline |
Relative time value to be used as the reference category. The corresponding dummy is excluded from the regression. Must be within the specified lead/lag range. |
interval |
Time interval between observations (e.g., 1 for yearly
data, 5 for 5-year intervals). |
time_transform |
Logical. If TRUE, converts the time
variable into a sequential index (1, 2, 3, …) within each unit. Useful
for irregular time (e.g., Date). Default is FALSE. |
unit |
Required if time_transform = TRUE. Specifies the panel
unit identifier (e.g., firm_id). |
staggered |
Logical. If TRUE, allows for unit-specific treatment
timing (staggered adoption). Default is FALSE. |
conf.level |
Numeric vector of confidence levels (e.g.,
c(0.90, 0.95, 0.99); default: 0.95). |
event_study <- run_es(
data = df1,
outcome = y,
treatment = treat,
time = period,
timing = 6,
fe = ~ id + period,
lead_range = 5,
lag_range = 4,
cluster = ~ id,
baseline = -1,
interval = 1,
conf.level = c(0.90, 0.95, 0.99)
)fe must be a one-sided formula (e.g.,
~ firm_id + year).cluster can be a one-sided formula or a character
vector.event_study <- run_es(
data = df1,
outcome = y,
treatment = treat,
time = period,
timing = 6,
fe = ~ id + period,
lead_range = 5,
lag_range = 4,
covariates = ~ cov1 + cov2 + cov3,
cluster = ~ id,
baseline = -1,
interval = 1
)Date), with
time_transformdf_alt <- df1 |>
dplyr::mutate(
year = rep(2001:2010, times = 108),
date = as.Date(paste0(year, "-01-01"))
)
event_study_alt <- run_es(
data = df_alt,
outcome = y,
treatment = treat,
time = date,
timing = 9, # Use index, not the original Date
fe = ~ id + period,
lead_range = 3,
lag_range = 3,
cluster = ~ id,
baseline = -1,
time_transform = TRUE,
unit = id
)Note:
Whentime_transform = TRUE, specifytimingas an index (e.g., 9 = 9th observation in unit).
Currently,time_transform = TRUEcannot be combined withstaggered = TRUE(future versions may support this).
plot_es()plot_es() visualizes results using ggplot2.
By default, it plots a ribbon for the 95% CI, but supports error bars,
CI level selection, and multiple themes.
| Argument | Description |
|---|---|
| data | Data frame from run_es() |
| ci_level | Confidence interval (default: 0.95) |
| type | “ribbon” (default) or “errorbar” |
| vline_val | X for vertical line (default: 0) |
| vline_color | Color for vline (default: “#000”) |
| hline_val | Y for horizontal line (default: 0) |
| hline_color | Color for hline (default: “#000”) |
| linewidth | Line width (default: 1) |
| pointsize | Point size (default: 2) |
| alpha | Ribbon transparency (default: 0.2) |
| barwidth | Errorbar width (default: 0.2) |
| color | Point/line color (default: “#B25D91FF”) |
| fill | Ribbon color (default: “#B25D91FF”) |
| theme_style | Theme: “bw” (default), “minimal”, “classic” |
plot_es(event_study)
plot_es(event_study, type = "errorbar")
plot_es(event_study, type = "ribbon", ci_level = 0.9, theme_style = "minimal")
plot_es(event_study, type = "errorbar", ci_level = 0.99) + ggplot2::ggtitle("Event Study, 99% CI")Further customization with ggplot2 is fully
supported:
plot_es(event_study, type = "errorbar") +
ggplot2::scale_x_continuous(breaks = seq(-5, 5, by = 1)) +
ggplot2::ggtitle("Result of Event Study")staggered = TRUE with
time_transform = TRUEtiming to accept original time values (e.g.,
Date), not just indexIf you find an issue or want to contribute, please use the GitHub Issues page.
Happy analyzing!🥂
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.