PowerAnalysis methodology review (PR-A): Bloom 1995 + Burlig 2020 source audits by igerber · Pull Request #506 · igerber/diff-diff · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TODO.md
13 changes: 11 additions & 2 deletions diff_diff/power.py
Original file line number Diff line number Diff line change
Expand Up @@ -1224,11 +1224,17 @@ class PowerAnalysis:
+ 1/n_control_post + 1/n_control_pre)

For panel DiD with T periods:
Var(ATT) = sigma^2 * (1/(N_treated * T) + 1/(N_control * T))
* (1 + (T-1)*rho) / (1 + (T-1)*rho)
Var(ATT) = sigma^2 * (1/N_treated + 1/N_control)
* (1 + (T-1)*rho) / T

Where rho is the intra-cluster correlation coefficient.

These analytical formulas are under methodology review (2026-05): the panel variance uses an
equicorrelated/Moulton ``(1 + (T-1)*rho)/T`` design effect, which is **not** Burlig et al.'s
serial-correlation-robust (SCR) variance, and the critical values use the normal (z)
approximation (Bloom) rather than Burlig's t-distribution. See ``docs/methodology/REGISTRY.md``
``## PowerAnalysis`` and the source audits under ``docs/methodology/papers/``.

References
----------
Bloom, H. S. (1995). "Minimum Detectable Effects."
Expand Down Expand Up @@ -1901,6 +1907,9 @@ def simulate_power(
3. Repeat n_simulations times
4. Power = fraction of simulations where p-value < alpha

The analytical reference formulas this Monte Carlo path complements are under methodology
review; see ``docs/methodology/REGISTRY.md`` ``## PowerAnalysis``.

References
----------
Burlig, F., Preonas, L., & Woerman, M. (2020). "Panel Data and Experimental Design."
Expand Down
17 changes: 16 additions & 1 deletion docs/methodology/REGISTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3211,6 +3211,21 @@ Violation types:

*Estimator equation (as implemented):*

- **Note:** The formulas in this "Estimator equation" block are under active methodology review
(2026-05; source audits at `docs/methodology/papers/bloom-1995-review.md` and
`docs/methodology/papers/burlig-preonas-woerman-2020-review.md`, against Bloom (1995) and Burlig,
Preonas & Woerman (2020)). The audits identified discrepancies with `diff_diff/power.py` to be
reconciled in a follow-up PR (tracked in `TODO.md`): (1) the MDE multiplier is written with the
t-distribution, but the analytical path uses the normal (z) approximation following Bloom — Burlig
Eq. 1 uses t; (2) the SE expression's `1/sqrt(1-R^2)` and cluster-size `m` terms are not what the
code implements (its `basic_did` variance is `2*sigma^2*(1/n_T+1/n_C)`, with no R^2 term); (3) the
sample-size formula below omits the `T(1-T)` allocation factor that the code applies (via
`treat_frac*(1-treat_frac)`); and (4) the panel `(1+(T-1)*rho)/T` factor is an
equicorrelated/Moulton design effect, **not** Burlig's serial-correlation-robust (SCR) variance
(their Eq. 2), so the Burlig attribution for the analytical panel path is an overclaim pending
re-attribution or implementation. These notes document the known state; this block is not yet a
corrected contract.

Minimum detectable effect (MDE):
```
MDE = (t_{α/2} + t_{1-κ}) × SE(τ̂)
Expand Down Expand Up @@ -3353,7 +3368,7 @@ should be a deliberate user choice.
| BaconDecomposition | bacondecomp | `bacon()` |
| HonestDiD | HonestDiD | `createSensitivityResults()` |
| PreTrendsPower | pretrends | `pretrends()` |
| PowerAnalysis | pwr / DeclareDesign | `pwr.t.test()` / simulation |
| PowerAnalysis | pwr / DeclareDesign / pcpanel | `pwr.t.test()` / simulation — **under review** (see `## PowerAnalysis` Note: the analytical path is normal-based, so `pwr.t.test` is not the faithful parity target; the panel parity reference is Stata `pcpanel`) |

---

Expand Down
168 changes: 168 additions & 0 deletions docs/methodology/papers/bloom-1995-review.md
Loading
Loading