| Title: | Staggered DiD Tools: Event Studies and ATT Aggregation |
|---|---|
| Description: | Provides tools for difference-in-differences (DiD) estimation and visualization with staggered adoption. Includes run_es() for event-study curves (dynamic effects by relative time) and calc_att() for aggregated ATT estimation (overall, by cohort, by calendar time). Supports multiple modern estimators: Callaway-Sant'Anna (2021), Sun-Abraham (2021), Borusyak-Jaravel-Spiess (2024), Wooldridge TWM, and Deb et al. FLEX. |
| Authors: | Yosuke Abe [aut, cre] |
| Maintainer: | Yosuke Abe <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.11.1 |
| Built: | 2026-05-31 02:53:21 UTC |
| Source: | https://github.com/yo5uke/fixes |
S3 method that plots an es_result (from run_es()).
It forwards arguments to plot_es().
## S3 method for class 'es_result' autoplot(object, ci_level = 0.95, type = "ribbon", ...)## S3 method for class 'es_result' autoplot(object, ci_level = 0.95, type = "ribbon", ...)
object |
An |
ci_level |
Confidence level (numeric, e.g., 0.95). Passed to |
type |
Plot type: |
... |
Additional arguments forwarded to |
A ggplot object.
# res <- run_es(...) # ggplot2::autoplot(res, ci_level = 0.95, type = "ribbon")# res <- run_es(...) # ggplot2::autoplot(res, ci_level = 0.95, type = "ribbon")
Estimates average treatment effects on the treated (ATT) using either the
Callaway-Sant'Anna (2021) or Borusyak-Jaravel-Spiess (2024) estimator,
aggregated to a single summary effect ("simple"), per-cohort effects
("by_cohort"), or per calendar-time effects ("by_time").
calc_att( data, outcome, treatment = NULL, time, timing, fe = NULL, covariates = NULL, cluster = NULL, weights = NULL, interval = 1, time_transform = FALSE, unit = NULL, estimator = c("cs", "bjs"), aggregation = c("simple", "by_cohort", "by_time"), control_group = c("nevertreated", "notyettreated"), anticipation = 0L, conf.level = 0.95, vcov = "HC1", vcov_args = list() )calc_att( data, outcome, treatment = NULL, time, timing, fe = NULL, covariates = NULL, cluster = NULL, weights = NULL, interval = 1, time_transform = FALSE, unit = NULL, estimator = c("cs", "bjs"), aggregation = c("simple", "by_cohort", "by_time"), control_group = c("nevertreated", "notyettreated"), anticipation = 0L, conf.level = 0.95, vcov = "HC1", vcov_args = list() )
data |
A data.frame containing panel data. |
outcome |
Unquoted outcome variable (name or expression, e.g., |
treatment |
Unused; reserved for future use. |
time |
Unquoted calendar time variable (numeric). |
timing |
Unquoted column giving each unit's first treatment period
( |
fe |
Ignored (CS and BJS absorb fixed effects internally). |
covariates |
Ignored; reserved for future use. |
cluster |
Ignored; reserved for future use. |
weights |
Ignored; reserved for future use. |
interval |
Numeric time spacing (default |
time_transform |
Logical; if |
unit |
Unquoted unit identifier (required). |
estimator |
Estimation strategy: |
aggregation |
Aggregation type: |
control_group |
For |
anticipation |
For |
conf.level |
Numeric confidence level(s) (default |
vcov |
Ignored (SE is analytical for CS; approximate for BJS). |
vcov_args |
Ignored. |
This function complements run_es(): use run_es() when you want a full
event-study curve (dynamic effects by relative time), and calc_att() when
you want aggregated ATT estimates that collapse the time dimension.
A data.frame of class "att_result" with columns:
groupCohort or calendar time (NA for "simple").
estimateATT point estimate.
std.errorStandard error.
statistict-statistic (estimate / std.error).
p.valueTwo-sided p-value (normal approximation).
conf_low_XX, conf_high_XX
CI bounds for each conf.level.
Attributes: aggregation, estimator, conf.level, N, N_units,
N_treated, N_nevertreated, control_group (CS only), att_gt (CS
raw ATT(g,t) table), tau_it (BJS unit-time effects table).
simple:
where is the mean over post-treatment periods.
by_cohort: per cohort.
by_time:
with .
BJS SEs are approximate (naive sample variance of unit-time effects). Cluster-robust SE for BJS aggregations is planned for v0.12.
run_es() for event-study (dynamic) estimates.
Estimates the contamination weights that
decompose each TWFE event-study coefficient into a
linear combination of cohort-specific ATTs (CATTs):
(Sun and Abraham 2021, Equation 20).
The weights are obtained via the OVB auxiliary regression (Eq. 12): for
each cohort-period CATT cell , regress the cohort-specific
indicator on all cohort-aggregated
relative-time indicators and two-way fixed effects.
The resulting regression coefficient on is
.
compute_contamination_weights( data, time, timing, unit, fe = NULL, baseline = -1L )compute_contamination_weights( data, time, timing, unit, fe = NULL, baseline = -1L )
data |
A data.frame with one row per unit-period (balanced panel). |
time |
Unquoted name of the calendar time variable (numeric). |
timing |
Unquoted name of the first-treatment-period variable;
|
unit |
Unquoted name of the unit identifier. |
fe |
One-sided fixed-effects formula, e.g. |
baseline |
Integer reference (baseline) period excluded from the TWFE
specification (default |
An object of class c("sa_contamination_weights", "data.frame")
with one row per (catt_cohort, catt_period, twfe_period) triple,
and columns:
catt_cohortCohort (first treatment period).
catt_periodRelative event time of the CATT.
twfe_periodRelative event time of the TWFE
coefficient being decomposed.
weightContamination weight .
is_ownLogical; TRUE when catt_period == twfe_period.
Attributes: baseline, cohorts, cohort_sizes, incl_periods.
Own-period cell (catt_period == twfe_period):
represents the weight the TWFE estimator
places on . Under the SA IW estimator these equal
the cohort-size weights .
Cross-period cell (catt_period != twfe_period):
Any non-zero weight indicates contamination: the TWFE coefficient
also picks up treatment effects from period
.
Verification: the OVB identity (property iii) holds
exactly, so up to
floating-point precision.
Sun, L. and Abraham, S. (2021). Estimating dynamic treatment effects in event studies with heterogeneous treatment effects. Journal of Econometrics, 225(2), 175–199.
plot_contamination_weights(), run_es()
## Not run: # Estimate contamination weights cw <- compute_contamination_weights( data = panel_data, time = year, timing = first_treat, unit = id, fe = ~ id + year, baseline = -1L ) print(cw) plot_contamination_weights(cw) ## End(Not run)## Not run: # Estimate contamination weights cw <- compute_contamination_weights( data = panel_data, time = year, timing = first_treat, unit = id, fe = ~ id + year, baseline = -1L ) print(cw) plot_contamination_weights(cw) ## End(Not run)
did_result objectReturns a single-row summary of model-level statistics from a run_did()
result. Delegates to broom::glance.fixest() which provides
nobs, r.squared, adj.r.squared, within.r.squared, AIC, BIC,
and related statistics.
glance.did_result(x, ...)glance.did_result(x, ...)
x |
A |
... |
Additional arguments passed to |
A one-row data frame of model-level statistics.
## Not run: res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) broom::glance(res) ## End(Not run)## Not run: res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) broom::glance(res) ## End(Not run)
Robust inference and sensitivity analysis for event-study / DiD designs following Rambachan and Roth (2023). Instead of assuming parallel trends holds exactly, it asks how large a violation of parallel trends would have to be before the causal conclusion changes, returning confidence sets for a post-treatment effect under a sequence of restrictions on the possible difference in trends.
Two restriction families are supported:
"relative_magnitude" (): post-treatment
violations are at most times the largest pre-treatment
violation (Rambachan & Roth 2023, Section 2.4.1).
"smoothness" (): the difference in trends
deviates from linearity by at most per period (Section 2.4.3).
Inference uses the Andrews-Roth-Pakes (ARP) conditional moment-inequality test (Section 3.2.1), which is uniformly valid and recommended for general restriction sets.
honest_sensitivity( object = NULL, type = c("relative_magnitude", "smoothness"), Mvec = NULL, l_vec = NULL, alpha = 0.05, gridPoints = 1000L, betahat = NULL, sigma = NULL, numPrePeriods = NULL, numPostPeriods = NULL )honest_sensitivity( object = NULL, type = c("relative_magnitude", "smoothness"), Mvec = NULL, l_vec = NULL, alpha = 0.05, gridPoints = 1000L, betahat = NULL, sigma = NULL, numPrePeriods = NULL, numPostPeriods = NULL )
object |
An |
type |
Restriction family: |
Mvec |
Numeric vector of restriction parameters. For
|
l_vec |
Numeric weight vector over post-treatment periods defining the
target |
alpha |
Significance level (default |
gridPoints |
Number of grid points for test inversion (default |
betahat |
Optional event-study coefficient vector (pre then post,
excluding the reference period), ordered by relative time. Required when
|
sigma |
Optional covariance matrix of |
numPrePeriods, numPostPeriods
|
Optional integer counts; inferred from
|
A data.frame of class "honest_result" with one row per
restriction value plus the original (parallel-trends) confidence interval,
with columns M, lb, ub, method, and type. The breakdown value
(largest restriction at which the robust CI still excludes 0) is stored in
attr(., "breakdown").
Rambachan, A. and Roth, J. (2023). A More Credible Approach to Parallel Trends. Review of Economic Studies, 90(5), 2555-2591.
Visualises the full cohort-by-period ATT(g,t) matrix stored in the
att_gt attribute of an es_result object produced by
run_es(estimator = "cs"). Two display styles are available:
"heatmap": a tile plot with calendar time on the
x-axis and cohort on the y-axis, colour-filled by the point
estimate. Cells whose pointwise confidence interval excludes zero are
marked with a filled dot; cells that are simultaneously significant
(when bootstrap data are available) are additionally marked with an open
diamond.
"facet": one panel per cohort showing ATT(g,t) over
calendar time with a pointwise confidence ribbon, mirroring
the style of plot_es(). A lighter simultaneous CI ribbon
is overlaid when bootstrap data are available.
Both types draw a vertical dashed line at (treatment onset)
for each cohort.
plot_att_gt( x, type = c("heatmap", "facet"), ci_level = 0.95, zero_line = TRUE, theme = c("bw", "minimal", "classic"), color = "#B25D91FF", fill = "#B25D91FF", alpha = 0.2 ) ## S3 method for class 'att_gt_result' autoplot(object, ...)plot_att_gt( x, type = c("heatmap", "facet"), ci_level = 0.95, zero_line = TRUE, theme = c("bw", "minimal", "classic"), color = "#B25D91FF", fill = "#B25D91FF", alpha = 0.2 ) ## S3 method for class 'att_gt_result' autoplot(object, ...)
x |
An |
type |
|
ci_level |
Confidence level for pointwise intervals (default 0.95). |
zero_line |
Logical; draw a horizontal reference line at zero in the
|
theme |
One of |
color |
Line and point colour used in the |
fill |
Ribbon fill colour in the |
alpha |
Ribbon transparency in the |
object |
An |
... |
Passed to |
A ggplot2::ggplot() object.
When attr(x, "bootstrap") is present (i.e., run_es() was
called with bootstrap = TRUE), both plot types add simultaneous
inference overlays sourced from the (g,t)-level bootstrap object.
## Not run: cs_result <- run_es(data = mydata, outcome = y, time = year, timing = g, unit = id, fe = ~id + year, staggered = TRUE, estimator = "cs") plot_att_gt(cs_result) plot_att_gt(cs_result, type = "facet") ## End(Not run)## Not run: cs_result <- run_es(data = mydata, outcome = y, time = year, timing = g, unit = id, fe = ~id + year, staggered = TRUE, estimator = "cs") plot_att_gt(cs_result) plot_att_gt(cs_result, type = "facet") ## End(Not run)
Creates a ggplot2 tile heatmap of the contamination weights returned by
compute_contamination_weights().
Each cell at position (twfe_period, catt_label) shows the
weight : how much of
leaks into the TWFE coefficient .
Diagonal cells (catt_period == twfe_period): own-period
weights (sum across cohorts should be ).
Off-diagonal cells: cross-period contamination (ideally close to zero under treatment effect homogeneity).
plot_contamination_weights( x, limit_abs = NULL, midpoint = 0, low = "#2166AC", mid = "white", high = "#B2182B", theme = c("bw", "minimal", "classic"), show_values = FALSE, value_digits = 2L )plot_contamination_weights( x, limit_abs = NULL, midpoint = 0, low = "#2166AC", mid = "white", high = "#B2182B", theme = c("bw", "minimal", "classic"), show_values = FALSE, value_digits = 2L )
x |
An |
limit_abs |
Numeric; symmetric colour scale limit |
midpoint |
Numeric; midpoint of the diverging colour scale (default 0). |
low |
Colour for negative weights (default |
mid |
Colour for zero weight (default |
high |
Colour for positive weights (default |
theme |
Character; |
show_values |
Logical; overlay weight values in each tile (default
|
value_digits |
Integer; decimal digits when |
A ggplot2::ggplot() object.
compute_contamination_weights()
Plot event-study results with ribbons or error bars
plot_es( data, ci_level = 0.95, type = "ribbon", vline_val = 0, vline_color = "#000", hline_val = 0, hline_color = "#000", linewidth = 1, pointsize = 2, alpha = 0.2, barwidth = 0.2, color = "#B25D91FF", fill = "#B25D91FF", theme_style = "bw", show_simultaneous = FALSE )plot_es( data, ci_level = 0.95, type = "ribbon", vline_val = 0, vline_color = "#000", hline_val = 0, hline_color = "#000", linewidth = 1, pointsize = 2, alpha = 0.2, barwidth = 0.2, color = "#B25D91FF", fill = "#B25D91FF", theme_style = "bw", show_simultaneous = FALSE )
data |
An object of class |
ci_level |
Confidence level to display (e.g., 0.95). |
type |
One of |
vline_val, hline_val
|
Numeric locations for vertical/horizontal reference lines (default 0). |
vline_color, hline_color
|
Colors for reference lines. |
linewidth, pointsize, alpha, barwidth
|
Styling parameters for lines/points/bands/bars. |
color, fill
|
Optional, override line/point color and ribbon fill. |
theme_style |
One of |
show_simultaneous |
Logical; if |
A ggplot object.
# Assuming `res <- run_es(...)` # p <- plot_es(res, ci_level = 0.95, type = "ribbon") # print(p)# Assuming `res <- run_es(...)` # p <- plot_es(res, ci_level = 0.95, type = "ribbon") # print(p)
Creates an interactive plotly visualization of event study results with hover-over displays showing coefficients, confidence intervals, and other details.
plot_es_interactive( data, ci_level = 0.95, vline_val = 0, hline_val = 0, vline_color = "#000", hline_color = "#000", color = "#B25D91FF", fill = "#B25D91FF", alpha = 0.2, linewidth = 2, markersize = 8, show_ribbon = TRUE, show_simultaneous = FALSE, height = NULL, width = NULL )plot_es_interactive( data, ci_level = 0.95, vline_val = 0, hline_val = 0, vline_color = "#000", hline_color = "#000", color = "#B25D91FF", fill = "#B25D91FF", alpha = 0.2, linewidth = 2, markersize = 8, show_ribbon = TRUE, show_simultaneous = FALSE, height = NULL, width = NULL )
data |
An object of class |
ci_level |
Confidence level to display (e.g., 0.95). Default is 0.95. |
vline_val |
Numeric location for vertical reference line (default 0). |
hline_val |
Numeric location for horizontal reference line (default 0). |
vline_color |
Color for vertical reference line (default "#000"). |
hline_color |
Color for horizontal reference line (default "#000"). |
color |
Point and line color (default "#B25D91FF"). |
fill |
Ribbon/band fill color (default "#B25D91FF"). |
alpha |
Ribbon transparency (default 0.2). |
linewidth |
Line width (default 2). |
markersize |
Marker size (default 8). |
show_ribbon |
Logical; if TRUE, shows confidence interval as a ribbon band (default TRUE). |
show_simultaneous |
Logical; if |
height |
Plot height in pixels (default NULL for auto). |
width |
Plot width in pixels (default NULL for auto). |
The hover tooltip displays:
Relative time to treatment
Point estimate (coefficient)
Confidence interval bounds
Standard error
P-value
Simultaneous CI bounds (when show_simultaneous = TRUE)
A plotly object that can be displayed interactively.
## Not run: # Assuming res <- run_es(...) plot_es_interactive(res) plot_es_interactive(res, ci_level = 0.99, show_ribbon = FALSE) plot_es_interactive(res, show_simultaneous = TRUE) ## End(Not run)## Not run: # Assuming res <- run_es(...) plot_es_interactive(res) plot_es_interactive(res, ci_level = 0.99, show_ribbon = FALSE) plot_es_interactive(res, show_simultaneous = TRUE) ## End(Not run)
Visualises the output of honest_sensitivity(): robust confidence intervals
for the target effect under progressively weaker parallel-trends restrictions
(increasing or ), alongside the original confidence
interval that assumes parallel trends holds exactly. This is the "top-down"
sensitivity plot of Rambachan and Roth (2023).
plot_honest(x, ...) ## S3 method for class 'honest_result' autoplot(object, ...)plot_honest(x, ...) ## S3 method for class 'honest_result' autoplot(object, ...)
x |
A |
... |
Unused. |
object |
A |
A ggplot object.
Estimates a classic difference-in-differences model of the form
outcome ~ D_it | fe using fixest::feols().
There are two ways to supply the treatment indicator:
Option A — pre-built D_it (maximum flexibility):
df$D <- as.integer(df$treated & df$year >= 2006) run_did(df, outcome = y, treatment = D, fe = ~ id + year)
Option B — timing-based construction (convenience; consistent with
run_es() and calc_att()):
run_did(df, outcome = y, treatment = treated, time = year, timing = 2006,
fe = ~ id + year)
Here treatment is a binary group indicator (1 = treated unit, 0 = control),
time is the calendar-time variable, and timing is the scalar treatment
onset period. Internally D_it = treatment * (time >= timing) is constructed
automatically. For staggered-adoption settings use calc_att(); for dynamic
event-study estimates use run_es().
run_did( data, outcome, treatment, timing = NULL, fe = NULL, unit = NULL, time = NULL, covariates = NULL, cluster = NULL, weights = NULL, conf.level = 0.95, vcov = "HC1", vcov_args = list() )run_did( data, outcome, treatment, timing = NULL, fe = NULL, unit = NULL, time = NULL, covariates = NULL, cluster = NULL, weights = NULL, conf.level = 0.95, vcov = "HC1", vcov_args = list() )
data |
A data.frame (panel format). |
outcome |
Unquoted outcome variable or expression (e.g., |
treatment |
Unquoted column name. When |
timing |
Numeric scalar. When provided, |
fe |
One-sided formula specifying fixed effects, e.g. |
unit |
Unquoted unit identifier column (for metadata and |
time |
Unquoted time variable column. Used for (a) |
covariates |
One-sided formula of additional controls, e.g. |
cluster |
Clustering specification: a one-sided formula ( |
weights |
Observation weights (formula or numeric vector). |
conf.level |
Confidence level(s) for CIs. Scalar or vector
(e.g., |
vcov |
VCOV type string passed to |
vcov_args |
Named list of additional arguments forwarded to
|
A did_result object (named list) with elements:
estimatesData frame with the treatment coefficient:
term, estimate, std.error, statistic, p.value, and
conf_low_XX/conf_high_XX for each conf.level entry.
modelThe underlying fixest model object.
Attributes: call, formula_str, outcome, treatment, timing,
fe, vcov_type, cluster_vars, conf.level, N, N_units,
N_treated, unit, time.
## Not run: # Option A: pre-built D_it df$D <- as.integer(df$treated & df$year >= 2006) res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) # Option B: timing-based construction res <- run_did(df, outcome = y, treatment = treated, time = year, timing = 2006, fe = ~ id + year) # Cluster-robust SE res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year, cluster = ~ id) print(res) broom::tidy(res) broom::glance(res) # modelsummary::modelsummary(res) ## End(Not run)## Not run: # Option A: pre-built D_it df$D <- as.integer(df$treated & df$year >= 2006) res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) # Option B: timing-based construction res <- run_did(df, outcome = y, treatment = treated, time = year, timing = 2006, fe = ~ id + year) # Cluster-robust SE res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year, cluster = ~ id) print(res) broom::tidy(res) broom::glance(res) # modelsummary::modelsummary(res) ## End(Not run)
Runs an event study regression on panel data, supporting both classic (universal timing) and staggered (unit-varying timing via sunab).
The function builds the design (lead/lag factor or sunab), estimates with fixest::feols(), and returns a tidy table with metadata.
run_es( data, outcome, treatment = NULL, time, timing, fe = NULL, lead_range = NULL, lag_range = NULL, covariates = NULL, cluster = NULL, weights = NULL, baseline = -1L, interval = 1, time_transform = FALSE, unit = NULL, staggered = FALSE, method = c("classic", "sunab"), estimator = c("twfe", "cs", "sa", "bjs", "twm", "flex"), control_group = c("nevertreated", "notyettreated"), anticipation = 0L, conf.level = 0.95, vcov = "HC1", vcov_args = list(), bootstrap = FALSE, B = 999L, alpha = 0.05, boot_seed = NULL, group = NULL, trends = FALSE )run_es( data, outcome, treatment = NULL, time, timing, fe = NULL, lead_range = NULL, lag_range = NULL, covariates = NULL, cluster = NULL, weights = NULL, baseline = -1L, interval = 1, time_transform = FALSE, unit = NULL, staggered = FALSE, method = c("classic", "sunab"), estimator = c("twfe", "cs", "sa", "bjs", "twm", "flex"), control_group = c("nevertreated", "notyettreated"), anticipation = 0L, conf.level = 0.95, vcov = "HC1", vcov_args = list(), bootstrap = FALSE, B = 999L, alpha = 0.05, boot_seed = NULL, group = NULL, trends = FALSE )
data |
A data.frame containing panel data. |
outcome |
Unquoted outcome (name or expression, e.g., |
treatment |
Unquoted treatment indicator (0/1 or logical). Used only when |
time |
Unquoted time variable (numeric or Date). |
timing |
For |
fe |
One-sided fixed-effects formula, e.g., |
lead_range, lag_range
|
Integers for pre/post windows. If |
covariates |
One-sided formula of additional controls, e.g., |
cluster |
Cluster specification (one-sided formula like |
weights |
Observation weights (a name/one-sided formula or a numeric vector of length |
baseline |
Integer baseline period (default |
interval |
Numeric spacing of the time variable (default |
time_transform |
Logical; if |
unit |
Unit identifier variable (required when |
staggered |
Logical; if |
method |
Either |
estimator |
Estimation strategy: |
control_group |
For |
anticipation |
For |
conf.level |
Numeric vector of confidence levels (default |
vcov |
VCOV type passed to |
vcov_args |
List of additional arguments forwarded to |
bootstrap |
Logical; if |
B |
Integer number of bootstrap draws (default |
alpha |
Significance level for the simultaneous band (default |
boot_seed |
Integer seed for the bootstrap RNG; |
group |
Unquoted group identifier for |
trends |
Logical; for |
A data.frame of class "es_result" with columns:
term, estimate, std.error, statistic, p.value
conf_low_XX, conf_high_XX (for each requested conf.level)
relative_time (integer; 0 = event), is_baseline (logical; marks the reference period)
Attributes include: lead_range, lag_range, baseline, interval, call, model_formula, conf.level,
N, N_units, N_treated, N_nevertreated, fe, vcov_type, cluster_vars, staggered, sunab_used.
One-step event study: specify outcome, treatment, time, timing, fixed effects, and (optionally) covariates.
Switch between Classic (factor expansion) and Staggered-SAFE (method = "sunab").
Flexible clustering, weights, and VCOV choices (e.g., vcov = "HC1" | "HC3" | "CR2" | "iid" ...).
Automatic lead/lag window detection and customizable baseline period.
Returns an "es_result" object compatible with print() and autoplot().
did_result objectReturns a tidy data frame of model coefficients from a run_did() result.
Delegates to broom::tidy.fixest() on the underlying fixest model so
that all regressors (treatment and covariates) appear in the output — the
format expected by modelsummary::modelsummary().
## S3 method for class 'did_result' tidy(x, conf.int = FALSE, conf.level = 0.95, ...)## S3 method for class 'did_result' tidy(x, conf.int = FALSE, conf.level = 0.95, ...)
x |
A |
conf.int |
Logical; add |
conf.level |
Confidence level for |
... |
Additional arguments passed to |
A data frame with columns term, estimate, std.error,
statistic, p.value (and optionally conf.low, conf.high).
## Not run: res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) broom::tidy(res) broom::tidy(res, conf.int = TRUE) ## End(Not run)## Not run: res <- run_did(df, outcome = y, treatment = D, fe = ~ id + year) broom::tidy(res) broom::tidy(res, conf.int = TRUE) ## End(Not run)