moderndid.create_sensitivity_results_rm#
- moderndid.create_sensitivity_results_rm(betahat, sigma, num_pre_periods, num_post_periods, bound='deviation from parallel trends', method='C-LF', m_bar_vec=None, l_vec=None, monotonicity_direction=None, bias_direction=None, alpha=0.05, grid_points=1000, grid_lb=None, grid_ub=None)[source]#
Perform sensitivity analysis using relative magnitude bounds.
Implements methods for robust inference using the relative magnitudes restriction \(\Delta^{RM}(\bar{M})\), following [1]. This restriction bounds post-treatment violations of parallel trends by \(\bar{M}\) times the maximum pre-treatment violation, formalizing the intuition that confounding factors in the post-treatment period should be similar in magnitude to those observed pre-treatment. When \(\bar{M} = 1\), the worst-case post-treatment violation is bounded by the maximum pre-treatment violation. This function computes confidence intervals across a range of \(\bar{M}\) values, facilitating sensitivity analysis.
- Parameters:
- betahat
numpy.ndarray Estimated event study coefficients.
- sigma
numpy.ndarray Covariance matrix of betahat.
- num_pre_periods
int Number of pre-treatment periods.
- num_post_periods
int Number of post-treatment periods.
- bound
str, default=”deviationfromparalleltrends” Type of bound:
“Deviation from parallel trends”: \(\Delta^{RM}\) and variants
“Deviation from linear trend”: \(\Delta^{SDRM}\) and variants
- method
str, default=”C-LF” Confidence interval method: “Conditional” or “C-LF”.
- m_bar_vec
numpy.ndarray, optional Vector of \(\bar{M}\) values. Default is 10 values from 0 to 2.
- l_vec
numpy.ndarray, optional Vector of weights for parameter of interest.
- monotonicity_direction
str, optional Direction of monotonicity restriction: “increasing” or “decreasing”.
- bias_direction
str, optional Direction of bias restriction: “positive” or “negative”.
- alpha
float, default=0.05 Significance level.
- grid_points
int, default=1000 Number of grid points for conditional methods.
- grid_lb
float, optional Lower bound for grid search.
- grid_ub
float, optional Upper bound for grid search.
- betahat
- Returns:
polars.DataFrameDataFrame with columns: lb, ub, method, Delta, Mbar.
Notes
Deviation from linear trend requires at least 3 pre-treatment periods.
References
[1]Rambachan, A., & Roth, J. (2023). A More Credible Approach to Parallel Trends. Review of Economic Studies.
Examples
To use this function directly, we need to compute an event study and extract the estimates and covariance matrix. If you’re using moderndid’s built-in estimators, you can use the
honest_didfunction to process the event study and extract the estimates and covariance matrix for you.If you’re using an external estimator, you will need to extract the influence functions and construct the covariance matrix. Then, you can use the
create_sensitivity_results_rmfunction to run the sensitivity analysis.In [1]: import numpy as np ...: from moderndid import att_gt, aggte, load_mpdta ...: from moderndid.didhonest import create_sensitivity_results_rm ...: df = load_mpdta() ...: gt_result = att_gt( ...: data=df, ...: yname="lemp", ...: tname="year", ...: gname="first.treat", ...: idname="countyreal", ...: est_method="dr", ...: boot=False ...: ) ...: es_result = aggte(gt_result, type="dynamic") ...:
Suppose this is an external estimator. We can extract the influence functions and construct the covariance matrix, removing the reference period.
In [2]: influence_func = es_result.influence_func ...: event_times = es_result.event_times ...: ref_idx = np.where(event_times == -1)[0][0] ...: att_no_ref = np.delete(es_result.att_by_event, ref_idx) ...: influence_no_ref = np.delete(influence_func, ref_idx, axis=1) ...: n = influence_no_ref.shape[0] ...: vcov = influence_no_ref.T @ influence_no_ref / (n * n) ...: num_pre = int(np.sum(np.delete(event_times, ref_idx) < -1)) ...: num_post = len(att_no_ref) - num_pre ...:
Finally, we run the sensitivity analysis with different values of \(\bar{M}\) bounding how large post-treatment violations can be relative to pre-treatment violations.
In [3]: results = create_sensitivity_results_rm( ...: betahat=att_no_ref, ...: sigma=vcov, ...: num_pre_periods=num_pre, ...: num_post_periods=num_post, ...: m_bar_vec=[0.0, 0.5, 1.0] ...: ) ...: results ...: Out[3]: shape: (3, 5) ┌───────────┬──────────┬────────┬─────────┬──────┐ │ lb ┆ ub ┆ method ┆ delta ┆ Mbar │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str ┆ str ┆ f64 │ ╞═══════════╪══════════╪════════╪═════════╪══════╡ │ -0.042424 ┆ 0.002561 ┆ C-LF ┆ DeltaRM ┆ 0.0 │ │ -0.045739 ┆ 0.006349 ┆ C-LF ┆ DeltaRM ┆ 0.5 │ │ -0.051421 ┆ 0.012505 ┆ C-LF ┆ DeltaRM ┆ 1.0 │ └───────────┴──────────┴────────┴─────────┴──────┘