diff_diff.PreTrendsPower#
- class diff_diff.PreTrendsPower[source]#
Bases:
objectPre-trends power analysis (Roth 2022).
Computes the power of pre-trends tests to detect violations of parallel trends, and the minimum detectable violation (MDV).
- Parameters:
alpha (float, default=0.05) – Significance level for the pre-trends test.
power (float, default=0.80) – Target power level for MDV calculation.
violation_type (str, default='linear') – Type of violation pattern to consider: - ‘linear’: Violations follow a linear trend (most common) - ‘constant’: Same violation in all pre-periods - ‘last_period’: Violation only in the last pre-period - ‘custom’: User-specified violation pattern (via violation_weights)
violation_weights (array-like, optional) – Custom weights for violation pattern. Length must equal number of pre-periods. Only used when violation_type=’custom’.
pretest_form ({'nis', 'wald'}, default='nis') –
Pre-trends test acceptance-region form:
'nis': Roth (2022) no-individually-significant pretest (Section II.A-B). Acceptance region isB_NIS(Σ) = { b : |b_t| <= z_{1-α/2} σ_t for all t }. Power computed via multivariate normal box probability. This is the new default (PR-B 2026-05-17), matching both the paper’s primary analysis and the Rpretrendspackage.'wald': Noncentral chi-squared on the quadratic formδ' Σ_22^{-1} δ(the shipped behavior prior to PR-B 2026-05-17). Retained as a paper-supported alternative under Propositions 1+3+4 (Wald acceptance region is a convex ellipsoid, so all four propositions apply). Use this for backwards-compat with shipped numerical baselines.
Examples
Basic usage with MultiPeriodDiD results:
>>> from diff_diff import MultiPeriodDiD >>> from diff_diff.pretrends import PreTrendsPower >>> >>> # Fit event study >>> mp_did = MultiPeriodDiD() >>> results = mp_did.fit(data, outcome='y', treatment='treated', ... time='period', post_periods=[4, 5, 6, 7]) >>> >>> # Analyze pre-trends power >>> pt = PreTrendsPower(alpha=0.05, power=0.80) >>> power_results = pt.fit(results) >>> print(power_results.summary()) >>> >>> # Get power curve >>> curve = pt.power_curve(results) >>> curve.plot()
Notes
The pre-trends test is typically a joint test that all pre-period coefficients are zero. This test has limited power to detect small violations, especially when:
There are few pre-periods
Standard errors are large
The violation pattern is smooth (e.g., linear trend)
Passing a pre-trends test does NOT mean parallel trends holds. It means violations smaller than the MDV cannot be ruled out. For robust inference, combine with HonestDiD sensitivity analysis.
References
- Roth, J. (2022). Pretest with Caution: Event-Study Estimates after Testing
for Parallel Trends. American Economic Review: Insights, 4(3), 305-322.
Methods
__init__([alpha, power, violation_type, ...])fit(results[, M, pre_periods])Compute pre-trends power analysis.
get_params()Get parameters for this estimator.
power_at(results, M[, pre_periods])Compute power to detect a specific violation magnitude.
power_curve(results[, M_grid, n_points, ...])Compute power across a range of violation magnitudes.
sensitivity_to_honest_did(results[, pre_periods])Compare pre-trends power analysis with HonestDiD sensitivity.
set_params(**params)Set parameters for this estimator.
- __init__(alpha=0.05, power=0.8, violation_type='linear', violation_weights=None, pretest_form='nis')[source]#
- classmethod __new__(*args, **kwargs)#