| Title: | Plausible Bounds for Treatment Path Estimates |
|---|---|
| Description: | Enhances dynamic effect plots as suggested in Freyaldenhoven and Hansen (2026) <https://simonfreyaldenhoven.github.io/papers/Plausible_bounds.pdf>. Data-driven smoothing delivers a smooth estimated path with potentially improved point estimation properties and confidence regions covering a surrogate that can be substantially tighter than conventional pointwise or uniform bands. |
| Authors: | Simon Freyaldenhoven [aut, cph], Christian Hansen [aut, cph], Ryan Kobler [aut, cre, cph] |
| Maintainer: | Ryan Kobler <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.1 |
| Built: | 2026-05-21 06:02:14 UTC |
| Source: | https://github.com/simonfreyaldenhoven/plausibounds |
Enhances dynamic effect plots as suggested in Freyaldenhoven and Hansen (2026). Data-driven smoothing delivers a smooth estimated path with potentially improved point estimation properties and confidence regions covering a surrogate that can be substantially tighter than conventional pointwise or uniform bands.
plausible_bounds: Calculate plausible bounds
create_plot: Create plots of the bounds
The package includes example datasets to demonstrate the functionality:
estimates_constant and var_constant:
A simple case with constant estimates and no correlation
estimates_bighump and var_bighump:
A case with sinusoidal estimates and moderate correlation
estimates_smooth and var_smooth:
A smooth case with effects that slowly level off and no correlation, from Figure 1 of Freyaldenhoven and Hansen (2026)
This function creates a plot of plausible bounds from a plausible_bounds object. The plot displays plausible bounds as the main visualization, with optional pointwise and sup-t bounds overlays. Supports event study designs with pre-treatment periods.
create_plot( result, show_supt = TRUE, show_pointwise = TRUE, show_annotations = TRUE )create_plot( result, show_supt = TRUE, show_pointwise = TRUE, show_annotations = TRUE )
result |
A plausible_bounds object returned by the plausible_bounds() function |
show_supt |
Whether to show sup-t bounds (default: TRUE) |
show_pointwise |
Whether to show pointwise bounds (default: TRUE) |
show_annotations |
Whether to show annotations with test statistics and ATE (default: TRUE) |
A ggplot2 object
# Example with bighump estimates and correlation between estimates data(estimates_bighump) data(var_bighump) result_complex <- plausible_bounds(estimates_bighump[1:4], var_bighump[1:4, 1:4]) plot_complex <- create_plot(result_complex)# Example with bighump estimates and correlation between estimates data(estimates_bighump) data(var_bighump) result_complex <- plausible_bounds(estimates_bighump[1:4], var_bighump[1:4, 1:4]) plot_complex <- create_plot(result_complex)
A dataset containing estimates with a curved sinusoidal pattern in the first 6 periods that then converges to zero for the remaining 30 periods. The effect is a smooth curved trajectory with a large dip before the treatment effect quickly returns to 0. Generated with moderate correlation (rho = 0.5).
estimates_bighumpestimates_bighump
A numeric vector with 36 elements
Generated from simulation with sinusoidal design and moderate correlation (rho = 0.5)
data(estimates_bighump) data(var_bighump) result <- plausible_bounds(estimates_bighump[1:4], var_bighump[1:4, 1:4]) create_plot(result)data(estimates_bighump) data(var_bighump) result <- plausible_bounds(estimates_bighump[1:4], var_bighump[1:4, 1:4]) create_plot(result)
A dataset containing estimates from a simple constant design, no correlation across horizons.
estimates_constantestimates_constant
A numeric vector with 12 elements
Generated from simulation with constant design and no correlation across horizons
data(estimates_constant) data(var_constant) result <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) create_plot(result)data(estimates_constant) data(var_constant) result <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) create_plot(result)
A dataset containing smooth treatment effect estimates that dip down and then converge to zero. The first 8 observations comprise the preperiods, the next 36 are post-period.
estimates_smoothestimates_smooth
A numeric vector with 44 elements (8 preperiods, 36 postperiods)
Point estimates from Figure 1 of Freyaldenhoven and Hansen (2026)
data(estimates_smooth) data(var_smooth) result <- plausible_bounds(estimates_smooth[9:13], var_smooth[9:13, 9:13]) create_plot(result)data(estimates_smooth) data(var_smooth) result <- plausible_bounds(estimates_smooth[9:13], var_smooth[9:13, 9:13]) create_plot(result)
This function calculates the plausible bounds for a vector of estimates along with average treatment effect, Wald tests, and optional pointwise/sup-t bounds. Supports pre-treatment periods for event study designs.
plausible_bounds( estimates, var, alpha = 0.05, preperiods = 0, include_pointwise = TRUE, include_supt = TRUE, parallel = FALSE, n_cores = NULL )plausible_bounds( estimates, var, alpha = 0.05, preperiods = 0, include_pointwise = TRUE, include_supt = TRUE, parallel = FALSE, n_cores = NULL )
estimates |
A numeric vector or single-row/single-column matrix of point estimates. If preperiods > 0, the first preperiods elements are pre-treatment estimates, followed by post-treatment estimates. |
var |
The variance-covariance matrix of the estimates |
alpha |
Significance level (default: 0.05) |
preperiods |
Number of pre-treatment periods (default: 0). Period 0 is assumed to be normalized and not included in estimates. |
include_pointwise |
Whether to include pointwise bounds (default: TRUE) |
include_supt |
Whether to include sup-t bounds (default: TRUE) |
parallel |
Whether to use parallel processing for restricted bounds calculation (default: FALSE) |
n_cores |
Number of cores to use for parallel processing (default: NULL, which uses detectCores() - 1). Only used when parallel = TRUE. |
A list containing:
alpha |
Significance level |
preperiods |
Number of pre-treatment periods |
wald_test |
List with post (and pre if preperiods > 0) Wald test results |
restricted_bounds |
Data frame with horizon, unrestr_est, restr_est, lower, upper |
restricted_bounds_metadata |
List with supt_critval, supt_b, degrees_of_freedom, K, lambda1, lambda2, restr_class, best_fit_model |
avg_treatment_effect |
List with estimate, se, lower, upper |
pointwise_bounds |
List with lower and upper vectors (if include_pointwise = TRUE) |
supt_bounds |
List with lower and upper vectors (if include_supt = TRUE) |
# Example with constant estimates and no correlation (simple case) data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) print(pb) summary(pb)# Example with constant estimates and no correlation (simple case) data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) print(pb) summary(pb)
Print method for plausible_bounds objects
## S3 method for class 'plausible_bounds' print(x, ...)## S3 method for class 'plausible_bounds' print(x, ...)
x |
A plausible_bounds object |
... |
Additional arguments passed to print |
Invisibly returns a plausible_bounds object and displays summary of main results
# Example with constant estimates and no correlation (simple case) data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) print(pb)# Example with constant estimates and no correlation (simple case) data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) print(pb)
Print method for summary.plausible_bounds objects
## S3 method for class 'summary.plausible_bounds' print(x, ...)## S3 method for class 'summary.plausible_bounds' print(x, ...)
x |
A summary.plausible_bounds object |
... |
Additional arguments passed to print |
Invisibly returns the input summary.plausible_bounds object and displays summary data.frame of restricted estimates and plausible bounds.
# Example with constant design and no correlation data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) pb_df <- summary(pb) print(pb_df)# Example with constant design and no correlation data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) pb_df <- summary(pb) print(pb_df)
Summary method for plausible_bounds objects
## S3 method for class 'plausible_bounds' summary(object, ...)## S3 method for class 'plausible_bounds' summary(object, ...)
object |
A plausible_bounds object |
... |
Additional arguments passed to summary |
A data.frame containing the horizon, unrestricted estimates, restricted estimates, and plausible bounds
# Example with constant estimates and no correlation (simple case) data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) print(pb) summary(pb)# Example with constant estimates and no correlation (simple case) data(estimates_constant) data(var_constant) pb <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) print(pb) summary(pb)
A variance matrix for the sinusoidal estimates with moderate correlation structure (rho = 0.5). This matrix has non-zero off-diagonal elements representing moderate correlation across time periods.
var_bighumpvar_bighump
A 36 x 36 matrix
Generated from simulation with sinusoidal design and moderate correlation (rho = 0.5)
data(estimates_bighump) data(var_bighump) result <- plausible_bounds(estimates_bighump[1:4], var_bighump[1:4, 1:4]) create_plot(result)data(estimates_bighump) data(var_bighump) result <- plausible_bounds(estimates_bighump[1:4], var_bighump[1:4, 1:4]) create_plot(result)
A variance matrix for the constant estimates. This is a diagonal matrix representing no correlation across time periods.
var_constantvar_constant
A 12 x 12 matrix
Generated from simulation with constant design and no correlation across horizons.
data(estimates_constant) data(var_constant) result <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) create_plot(result)data(estimates_constant) data(var_constant) result <- plausible_bounds(estimates_constant[1:4], var_constant[1:4, 1:4]) create_plot(result)
A variance matrix for the smooth estimates. This matrix captures the correlation structure of the estimates. The first 8 rows and 8 columns comprise the variance matrix for the 8 preperiods.
var_smoothvar_smooth
A 44 x 44 matrix
Variance Matrix from Figure 1 of Freyaldenhoven and Hansen (2026)
data(estimates_smooth) data(var_smooth) result <- plausible_bounds(estimates_smooth[9:13], var_smooth[9:13, 9:13]) create_plot(result)data(estimates_smooth) data(var_smooth) result <- plausible_bounds(estimates_smooth[9:13], var_smooth[9:13, 9:13]) create_plot(result)