PyMetaAnalysis 0.5.0__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/.gitignore +1 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/CHANGELOG.md +17 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/CITATION.cff +2 -2
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/PKG-INFO +9 -3
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/README.md +8 -2
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/adr/0002-statistical-policy.md +8 -2
- pymetaanalysis-0.6.0/docs/adr/0005-mantel-haenszel-risk-difference.md +65 -0
- pymetaanalysis-0.6.0/docs/adr/0006-peto-odds-ratio.md +87 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/development.md +2 -2
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/binary-outcomes.md +33 -5
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/method-selection.md +18 -11
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/provenance-reporting.md +12 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/r-interoperability.md +20 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/sensitivity-analysis.md +1 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/zero-events.md +30 -4
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/index.md +7 -5
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/installation.md +1 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/limitations.md +7 -4
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/methods/statistical-methods.md +78 -9
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/reference/api.md +14 -6
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/reference/results.md +11 -2
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/releasing.md +16 -17
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/validation.md +7 -2
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/mkdocs.yml +2 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/pyproject.toml +2 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/_version.py +1 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/binary_api.py +97 -19
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/effect_sizes/binary.py +94 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/estimators/__init__.py +3 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/estimators/mantel_haenszel.py +50 -7
- pymetaanalysis-0.6.0/src/meta_analyze/estimators/peto.py +154 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/reporting.py +22 -5
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/README.md +6 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/binary_metafor.json +60 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_binary_metafor.R +80 -16
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_binary.py +247 -1
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_estimators.py +62 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_properties.py +148 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_r_references.py +79 -9
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_reporting.py +42 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_sensitivity.py +24 -6
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_subgroups.py +18 -5
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/.github/workflows/ci.yml +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/.github/workflows/pages.yml +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/.github/workflows/release.yml +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/CONTRIBUTING.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/LICENSE +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/SECURITY.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/benchmarks/README.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/benchmarks/benchmark_core.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/adr/0001-optional-matplotlib.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/adr/0003-meta-regression-prediction-intervals.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/adr/0004-hartung-knapp-prediction-intervals.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/citation.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/getting-started.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/continuous-outcomes.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/generic-effects.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/input-data.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/meta-regression.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/guides/plotting.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/reference/report-schema.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/docs/stylesheets/extra.css +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/examples/README.md +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/examples/meta_regression.ipynb +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/examples/quickstart.ipynb +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/__init__.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/api.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/config.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/continuous_api.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/data.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/design_matrix.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/effect_sizes/__init__.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/effect_sizes/continuous.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/estimators/inverse_variance.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/estimators/meta_regression.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/estimators/tau2.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/exceptions.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/heterogeneity.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/plotting/__init__.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/plotting/_utils.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/plotting/forest.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/plotting/funnel.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/plotting/regression.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/plotting/subgroup_forest.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/provenance.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/py.typed +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/regression_api.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/regression_collinearity.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/regression_contrasts.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/regression_results.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/regression_sensitivity.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/results.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/sensitivity.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/src/meta_analyze/subgroups.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/binary_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/binary_sparse_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/continuous_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/continuous_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_continuous_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_generic_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_meta_regression_collinearity_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_meta_regression_contrasts_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_meta_regression_influence_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_meta_regression_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generate_workflow_metafor.R +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generic_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/generic_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/meta_regression_boundary_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/meta_regression_collinearity_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/meta_regression_contrasts_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/meta_regression_influence_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/meta_regression_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/meta_regression_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/workflow_input.csv +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/reference/workflow_metafor.json +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_api.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_continuous.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_documentation.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_funnel_plot.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_meta_regression.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_numerical_stability.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_plotting.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_reference_results.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_regression_collinearity.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_regression_contrasts.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_regression_influence.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_regression_plotting.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_regression_sensitivity.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tests/test_release_readiness.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tools/check_release.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tools/execute_notebooks.py +0 -0
- {pymetaanalysis-0.5.0 → pymetaanalysis-0.6.0}/tools/inspect_distribution.py +0 -0
|
@@ -6,6 +6,23 @@ Changes planned for the next release accumulate under `Unreleased`.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.6.0 - 2026-08-13
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- common-effect Peto one-step odds-ratio pooling, including Peto-specific
|
|
14
|
+
study estimates, O-minus-E heterogeneity, explicit approximation warnings,
|
|
15
|
+
provenance/report metadata, and independent R `metafor` references;
|
|
16
|
+
- common-effect Mantel-Haenszel risk-difference pooling with the
|
|
17
|
+
Sato-Greenland-Robins sampling variance, explicit method metadata,
|
|
18
|
+
sparse-table policy integration, and independent R `metafor` references.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- isolated builds temporarily cap Hatchling below 1.32 so the release
|
|
23
|
+
workflow continues to produce Core Metadata 2.4 accepted by Twine 6.2;
|
|
24
|
+
the cap can be removed once Twine validates Metadata 2.5.
|
|
25
|
+
|
|
9
26
|
## 0.5.0 - 2026-07-25
|
|
10
27
|
|
|
11
28
|
### Added
|
|
@@ -8,8 +8,8 @@ authors:
|
|
|
8
8
|
- family-names: Ding
|
|
9
9
|
given-names: Zhaobo
|
|
10
10
|
email: ding.zb@yahoo.com
|
|
11
|
-
version: 0.
|
|
12
|
-
date-released: 2026-
|
|
11
|
+
version: 0.6.0
|
|
12
|
+
date-released: 2026-08-13
|
|
13
13
|
repository-code: https://github.com/ZhaoboDing/PyMetaAnalysis
|
|
14
14
|
url: https://zhaoboding.github.io/PyMetaAnalysis/
|
|
15
15
|
license: MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyMetaAnalysis
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A pandas-first, auditable meta-analysis library for Python
|
|
5
5
|
Project-URL: Documentation, https://zhaoboding.github.io/PyMetaAnalysis/
|
|
6
6
|
Project-URL: Source, https://github.com/ZhaoboDing/PyMetaAnalysis
|
|
@@ -133,7 +133,7 @@ not individual-level or causal effects.
|
|
|
133
133
|
| Input | Effects | Pooling/models |
|
|
134
134
|
| --- | --- | --- |
|
|
135
135
|
| Effect + sampling variance or standard error | Generic | Common/random inverse variance |
|
|
136
|
-
| Two-group events + totals | OR, RR, RD | Common MH OR
|
|
136
|
+
| Two-group events + totals | OR, RR, RD | Common MH; common Peto OR; common/random IV |
|
|
137
137
|
| Two-group means + SDs + sizes | MD, Hedges' g | Common/random inverse variance |
|
|
138
138
|
| Effect + variance/SE + moderators | Generic | Common/mixed Meta-regression |
|
|
139
139
|
|
|
@@ -153,6 +153,12 @@ Sparse binary behavior is explicit: study-level and Mantel-Haenszel continuity
|
|
|
153
153
|
corrections are separate, relative-effect double-zero/double-all rows remain
|
|
154
154
|
visible as exclusions, and RD exposes
|
|
155
155
|
`rd_zero_variance="correct" | "exclude"`.
|
|
156
|
+
Peto OR uses raw tables for pooling and a separate one-step study estimator;
|
|
157
|
+
it always reports a caution that its approximation is intended for rare
|
|
158
|
+
outcomes, similar within-study arm sizes, and effects that are not large.
|
|
159
|
+
Common-effect MH risk differences use the Sato-Greenland-Robins sampling
|
|
160
|
+
variance; random-effects binary analyses continue to use inverse-variance
|
|
161
|
+
pooling.
|
|
156
162
|
|
|
157
163
|
## Inspect and report
|
|
158
164
|
|
|
@@ -252,7 +258,7 @@ python -m mkdocs serve
|
|
|
252
258
|
|
|
253
259
|
The test suite combines hand calculations, statistical invariants, numerical
|
|
254
260
|
edge cases, and committed R `metafor` reference fixtures. CI covers Python
|
|
255
|
-
3.10–3.
|
|
261
|
+
3.10–3.14, declared dependency lower bounds, strict typing/linting, docs, and
|
|
256
262
|
distribution builds.
|
|
257
263
|
|
|
258
264
|
This is independent cross-software validation, not a formal external
|
|
@@ -83,7 +83,7 @@ not individual-level or causal effects.
|
|
|
83
83
|
| Input | Effects | Pooling/models |
|
|
84
84
|
| --- | --- | --- |
|
|
85
85
|
| Effect + sampling variance or standard error | Generic | Common/random inverse variance |
|
|
86
|
-
| Two-group events + totals | OR, RR, RD | Common MH OR
|
|
86
|
+
| Two-group events + totals | OR, RR, RD | Common MH; common Peto OR; common/random IV |
|
|
87
87
|
| Two-group means + SDs + sizes | MD, Hedges' g | Common/random inverse variance |
|
|
88
88
|
| Effect + variance/SE + moderators | Generic | Common/mixed Meta-regression |
|
|
89
89
|
|
|
@@ -103,6 +103,12 @@ Sparse binary behavior is explicit: study-level and Mantel-Haenszel continuity
|
|
|
103
103
|
corrections are separate, relative-effect double-zero/double-all rows remain
|
|
104
104
|
visible as exclusions, and RD exposes
|
|
105
105
|
`rd_zero_variance="correct" | "exclude"`.
|
|
106
|
+
Peto OR uses raw tables for pooling and a separate one-step study estimator;
|
|
107
|
+
it always reports a caution that its approximation is intended for rare
|
|
108
|
+
outcomes, similar within-study arm sizes, and effects that are not large.
|
|
109
|
+
Common-effect MH risk differences use the Sato-Greenland-Robins sampling
|
|
110
|
+
variance; random-effects binary analyses continue to use inverse-variance
|
|
111
|
+
pooling.
|
|
106
112
|
|
|
107
113
|
## Inspect and report
|
|
108
114
|
|
|
@@ -202,7 +208,7 @@ python -m mkdocs serve
|
|
|
202
208
|
|
|
203
209
|
The test suite combines hand calculations, statistical invariants, numerical
|
|
204
210
|
edge cases, and committed R `metafor` reference fixtures. CI covers Python
|
|
205
|
-
3.10–3.
|
|
211
|
+
3.10–3.14, declared dependency lower bounds, strict typing/linting, docs, and
|
|
206
212
|
distribution builds.
|
|
207
213
|
|
|
208
214
|
This is independent cross-software validation, not a formal external
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
- Date: 2026-07-15
|
|
5
5
|
- Amendment: the prediction-interval variance decision is superseded by
|
|
6
6
|
[ADR 0004](0004-hartung-knapp-prediction-intervals.md).
|
|
7
|
+
- Amendment: the decision to defer Mantel-Haenszel risk differences is
|
|
8
|
+
superseded by [ADR 0005](0005-mantel-haenszel-risk-difference.md).
|
|
9
|
+
- Amendment: the decision to defer Peto pooling is superseded by
|
|
10
|
+
[ADR 0006](0006-peto-odds-ratio.md).
|
|
7
11
|
|
|
8
12
|
## Context
|
|
9
13
|
|
|
@@ -44,13 +48,15 @@ option, and a provenance transformation.
|
|
|
44
48
|
Mantel-Haenszel pooling remains a common-effect estimator for OR and RR. It
|
|
45
49
|
uses raw tables by default and has a correction setting separate from the one
|
|
46
50
|
used for individual-study effects. Random-effects Mantel-Haenszel, RD
|
|
47
|
-
Mantel-Haenszel, and Peto pooling
|
|
51
|
+
Mantel-Haenszel, and Peto pooling were outside the scope of this original
|
|
52
|
+
decision; ADRs 0005 and 0006 supersede the latter two deferrals.
|
|
48
53
|
|
|
49
54
|
### Heterogeneity
|
|
50
55
|
|
|
51
56
|
Cochran's Q, degrees of freedom, and p-value always use common-effect inverse-
|
|
52
57
|
variance weights. Common-effect and Mantel-Haenszel analyses use Q-based
|
|
53
|
-
I-squared and H-squared.
|
|
58
|
+
I-squared and H-squared. ADR 0006 adds Peto's estimator-specific Q while
|
|
59
|
+
retaining those Q-based inconsistency transformations.
|
|
54
60
|
|
|
55
61
|
Random-effects analyses use:
|
|
56
62
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# ADR 0005: Mantel-Haenszel risk difference
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-08-13
|
|
5
|
+
- Supersedes: the RD exclusion from the Mantel-Haenszel scope in
|
|
6
|
+
[ADR 0002](0002-statistical-policy.md)
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
ADR 0002 limited Mantel-Haenszel pooling to common-effect odds ratios and risk
|
|
11
|
+
ratios while the risk-difference estimator and its variance convention were
|
|
12
|
+
still undecided. This left inverse variance as the only pooling method for RD,
|
|
13
|
+
although conventional R implementations provide a common-effect MH RD.
|
|
14
|
+
|
|
15
|
+
The point estimator is straightforward, but several variance estimators have
|
|
16
|
+
appeared in the literature. The selected rule must work under both large-
|
|
17
|
+
stratum and sparse-data limiting models, preserve treatment/control symmetry,
|
|
18
|
+
and remain explicit in reports and cross-software validation.
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
|
|
22
|
+
PyMetaAnalysis supports `measure="RD", method="MH", model="common"`. With
|
|
23
|
+
treatment total `n1_i`, control total `n0_i`, total `N_i`, and
|
|
24
|
+
`w_i = n1_i n0_i / N_i`, the estimate is:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
RD_i = a_i / n1_i - c_i / n0_i
|
|
28
|
+
RD_MH = sum(w_i RD_i) / sum(w_i)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The normal confidence interval uses the Sato-Greenland-Robins sampling
|
|
32
|
+
variance. The resolved method options record
|
|
33
|
+
`mh_rd_variance="Sato-Greenland-Robins"`.
|
|
34
|
+
|
|
35
|
+
Raw tables are used for MH pooling by default. `mh_continuity_correction` and
|
|
36
|
+
`mh_correction_scope` remain the only settings that alter MH pooling tables;
|
|
37
|
+
the separate study-effect correction continues to control displayed study
|
|
38
|
+
uncertainty and the inverse-variance heterogeneity calculation. The existing
|
|
39
|
+
`rd_zero_variance` policy determines whether boundary studies enter all
|
|
40
|
+
synthesis calculations. A non-positive pooled Sato variance raises a domain
|
|
41
|
+
error instead of silently adding a correction.
|
|
42
|
+
|
|
43
|
+
Random-effects MH remains unsupported. Random-effects RD continues to use
|
|
44
|
+
inverse-variance pooling with an explicit tau-squared estimator.
|
|
45
|
+
|
|
46
|
+
## Validation
|
|
47
|
+
|
|
48
|
+
- direct formula tests cover the estimate, Sato variance, weights, and normal
|
|
49
|
+
interval;
|
|
50
|
+
- treatment/control swaps negate the estimate and mirror its interval without
|
|
51
|
+
changing the standard error;
|
|
52
|
+
- row reordering and common count scaling preserve the expected invariants;
|
|
53
|
+
- extreme finite counts exercise the overflow-safe scaled implementation;
|
|
54
|
+
- boundary-policy, explicit-correction, subgroup, leave-one-out, and
|
|
55
|
+
cumulative paths are covered; and
|
|
56
|
+
- fixed-version `metafor::rma.mh(measure="RD")` fixtures cover ordinary,
|
|
57
|
+
sparse, and explicitly corrected tables.
|
|
58
|
+
|
|
59
|
+
## Consequences
|
|
60
|
+
|
|
61
|
+
- common-effect OR, RR, and RD all support MH or inverse-variance pooling;
|
|
62
|
+
- study-table MH weights for RD are proportional to `n1_i n0_i / N_i`;
|
|
63
|
+
- the selected RD variance convention is recoverable from method metadata and
|
|
64
|
+
generated reports; and
|
|
65
|
+
- documentation must continue to distinguish MH RD from random-effects IV RD.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# ADR 0006: Peto one-step odds ratio
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-08-13
|
|
5
|
+
- Supersedes: the Peto deferral in
|
|
6
|
+
[ADR 0002](0002-statistical-policy.md)
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
Peto's one-step method is a conventional common-effect estimator for binary
|
|
11
|
+
outcomes and is particularly associated with rare-event meta-analysis. It is
|
|
12
|
+
not interchangeable with an ordinary inverse-variance odds ratio: it derives
|
|
13
|
+
both the study contribution and pooled estimate from observed-minus-expected
|
|
14
|
+
events and hypergeometric information.
|
|
15
|
+
|
|
16
|
+
The approximation can be biased when treatment and control group sizes differ
|
|
17
|
+
substantially within studies, effects are large, or events are not rare. Its
|
|
18
|
+
zero-cell behavior also differs from ordinary log odds ratios, so pooling and
|
|
19
|
+
display corrections must not be conflated.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
PyMetaAnalysis supports `measure="OR", method="Peto", model="common"` with
|
|
24
|
+
`ci_method="normal"`. `"peto_one_step"` is an accepted alias and the resolved
|
|
25
|
+
pooling method is `"peto"`.
|
|
26
|
+
|
|
27
|
+
For stratum `i`, let `O_i = a_i`, `m_i = a_i + c_i`, treatment and control
|
|
28
|
+
totals be `n1_i` and `n0_i`, and `N_i = n1_i + n0_i`. Define:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
E_i = m_i n1_i / N_i
|
|
32
|
+
V_i = m_i (N_i - m_i) n1_i n0_i / (N_i^2 (N_i - 1))
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The individual and pooled model-scale estimates are:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
y_i = (O_i - E_i) / V_i
|
|
39
|
+
Var(y_i) = 1 / V_i
|
|
40
|
+
y_Peto = sum(O_i - E_i) / sum(V_i)
|
|
41
|
+
Var(y_Peto) = 1 / sum(V_i)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Pooling always uses raw 2-by-2 tables. The existing
|
|
45
|
+
`continuity_correction` and `correction_scope` settings affect only displayed
|
|
46
|
+
study estimates and variances; there is no Peto pooling correction parameter.
|
|
47
|
+
Double-zero and double-all rows are excluded before every synthesis
|
|
48
|
+
calculation because they contain no relative-effect information.
|
|
49
|
+
|
|
50
|
+
Peto heterogeneity uses the fitted pooled coefficient and the same
|
|
51
|
+
observed-minus-expected contributions:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
Q = sum(((O_i - E_i) - y_Peto V_i)^2 / V_i)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Q-based I-squared and H-squared follow the project's common-effect
|
|
58
|
+
conventions. Method options record `peto_pooling_tables="raw"` and
|
|
59
|
+
`peto_heterogeneity="O-minus-E"`. Every Peto result carries an approximation
|
|
60
|
+
warning naming the rare-outcome, balanced-arm, and modest-effect conditions.
|
|
61
|
+
|
|
62
|
+
Random-effects Peto and Peto RR/RD are unsupported. Users requesting those
|
|
63
|
+
estimands must select an implemented inverse-variance or Mantel-Haenszel
|
|
64
|
+
combination explicitly.
|
|
65
|
+
|
|
66
|
+
## Validation
|
|
67
|
+
|
|
68
|
+
- direct formula tests cover study estimates, pooled estimate, variance,
|
|
69
|
+
weights, confidence interval, and Peto Q;
|
|
70
|
+
- treatment/control swapping reverses and exponentiates the log-OR limits as
|
|
71
|
+
expected, while row order leaves the fit unchanged;
|
|
72
|
+
- count scaling and extreme finite-count tests exercise overflow-safe
|
|
73
|
+
arithmetic;
|
|
74
|
+
- sparse tables verify that study-level correction does not alter raw Peto
|
|
75
|
+
pooling and that double-zero/double-all rows are excluded; and
|
|
76
|
+
- fixed-version `metafor::escalc(measure="PETO")` and `metafor::rma.peto()`
|
|
77
|
+
fixtures cover ordinary and sparse datasets.
|
|
78
|
+
|
|
79
|
+
## Consequences
|
|
80
|
+
|
|
81
|
+
- common-effect binary OR now offers MH, Peto, and inverse-variance pooling;
|
|
82
|
+
- Peto results remain on the log-OR model scale and use exponentiated display
|
|
83
|
+
values like other OR results;
|
|
84
|
+
- sensitivity, subgroup, provenance, reporting, and plotting workflows reuse
|
|
85
|
+
the same public result contracts; and
|
|
86
|
+
- documentation and reports must preserve the Peto applicability warning
|
|
87
|
+
rather than presenting it as a general sparse-data default.
|
|
@@ -11,7 +11,7 @@ cd PyMetaAnalysis
|
|
|
11
11
|
python -m pip install -e ".[test,dev,docs,plot]"
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
Use a supported Python version (3.10–3.
|
|
14
|
+
Use a supported Python version (3.10–3.14). Keep changes focused and preserve
|
|
15
15
|
unrelated worktree modifications.
|
|
16
16
|
|
|
17
17
|
## Run checks
|
|
@@ -31,7 +31,7 @@ python -m build
|
|
|
31
31
|
python tools/inspect_distribution.py dist
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
The CI matrix also tests Python 3.10–3.
|
|
34
|
+
The CI matrix also tests Python 3.10–3.14 and declared dependency lower bounds.
|
|
35
35
|
Install the `notebook` extra before running the notebook executor.
|
|
36
36
|
|
|
37
37
|
## Statistical changes
|
|
@@ -35,8 +35,33 @@ result = ma.meta_binary(
|
|
|
35
35
|
print(result.summary())
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Mantel-Haenszel pooling
|
|
39
|
-
`ci_method="normal"`.
|
|
38
|
+
Mantel-Haenszel pooling supports OR, RR, and RD with `model="common"` and
|
|
39
|
+
`ci_method="normal"`. MH risk differences use the Sato-Greenland-Robins
|
|
40
|
+
sampling variance, recorded in `dict(result.method.options)`.
|
|
41
|
+
|
|
42
|
+
## Peto common-effect odds ratio
|
|
43
|
+
|
|
44
|
+
Peto's one-step estimator is an explicit alternative for common-effect OR:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
peto = ma.meta_binary(
|
|
48
|
+
studies,
|
|
49
|
+
event_treat="events_t",
|
|
50
|
+
n_treat="total_t",
|
|
51
|
+
event_control="events_c",
|
|
52
|
+
n_control="total_c",
|
|
53
|
+
measure="OR",
|
|
54
|
+
method="Peto",
|
|
55
|
+
model="common",
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Peto pooling uses the raw 2-by-2 tables and its own observed-minus-expected
|
|
60
|
+
heterogeneity statistic. The study table contains Peto one-step effects;
|
|
61
|
+
`continuity_correction` affects those displayed study effects but not the
|
|
62
|
+
pooled result. Peto is intended for rare outcomes when treatment/control arm
|
|
63
|
+
sizes are similar within studies and effects are not large. The result always
|
|
64
|
+
retains this caveat in `warnings` and Methods text.
|
|
40
65
|
|
|
41
66
|
## Random-effects analysis
|
|
42
67
|
|
|
@@ -71,7 +96,8 @@ them to the generic inverse-variance model.
|
|
|
71
96
|
For OR and RR, `result.estimate` and `result.ci` stay on the log model scale.
|
|
72
97
|
Use `display_estimate` and `display_ci` for exponentiated ratios.
|
|
73
98
|
|
|
74
|
-
RD
|
|
99
|
+
For a common-effect RD, choose either MH or inverse-variance pooling explicitly.
|
|
100
|
+
The MH form is:
|
|
75
101
|
|
|
76
102
|
```python
|
|
77
103
|
result = ma.meta_binary(
|
|
@@ -81,7 +107,7 @@ result = ma.meta_binary(
|
|
|
81
107
|
event_control="events_c",
|
|
82
108
|
n_control="total_c",
|
|
83
109
|
measure="RD",
|
|
84
|
-
method="
|
|
110
|
+
method="MH",
|
|
85
111
|
model="common",
|
|
86
112
|
rd_zero_variance="correct",
|
|
87
113
|
)
|
|
@@ -91,6 +117,8 @@ result = ma.meta_binary(
|
|
|
91
117
|
their raw RD and uses corrected counts only for sampling variance. Use
|
|
92
118
|
`"exclude"` for a protocol that excludes these studies before all synthesis
|
|
93
119
|
calculations. See [zero-event studies](zero-events.md) for details.
|
|
120
|
+
Use `method="IV"` for random-effects RD or when inverse-variance common-effect
|
|
121
|
+
pooling is the prespecified estimator.
|
|
94
122
|
|
|
95
123
|
## Input validation
|
|
96
124
|
|
|
@@ -104,5 +132,5 @@ Sparse tables require additional decisions. Read
|
|
|
104
132
|
settings.
|
|
105
133
|
|
|
106
134
|
See [statistical methods](../methods/statistical-methods.md#binary-study-effects)
|
|
107
|
-
for the OR/RR/RD
|
|
135
|
+
for the OR/RR/RD, Mantel-Haenszel, and Peto equations, and
|
|
108
136
|
[validation](../validation.md) for cross-software coverage.
|
|
@@ -36,15 +36,21 @@ protocols.
|
|
|
36
36
|
| Data and model | Available pooling method |
|
|
37
37
|
| --- | --- |
|
|
38
38
|
| Generic effects, common or random | Inverse variance |
|
|
39
|
-
| Binary OR
|
|
40
|
-
| Binary
|
|
41
|
-
| Binary RD,
|
|
39
|
+
| Binary OR, common effect | Mantel-Haenszel, Peto, or inverse variance |
|
|
40
|
+
| Binary RR/RD, common effect | Mantel-Haenszel or inverse variance |
|
|
41
|
+
| Binary OR/RR/RD, random effects | Inverse variance |
|
|
42
42
|
| Continuous MD/SMD, common or random | Inverse variance |
|
|
43
43
|
|
|
44
44
|
Mantel-Haenszel and inverse variance are different estimators, not aliases.
|
|
45
45
|
PyMetaAnalysis does not extrapolate its common-effect Mantel-Haenszel weights
|
|
46
|
-
into an undocumented random-effects procedure. Mantel-Haenszel OR/RR
|
|
47
|
-
uses raw tables by default
|
|
46
|
+
into an undocumented random-effects procedure. Mantel-Haenszel OR/RR/RD
|
|
47
|
+
pooling uses raw tables by default. MH RD uses the Sato-Greenland-Robins
|
|
48
|
+
sampling variance; it is not a random-effects estimator.
|
|
49
|
+
|
|
50
|
+
Peto is a distinct common-effect OR estimator based on observed-minus-expected
|
|
51
|
+
events. Consider it only when outcomes are rare, treatment/control group sizes
|
|
52
|
+
are similar within each study, and effects are not large. It always uses raw
|
|
53
|
+
tables for pooling and is not an automatic sparse-data default.
|
|
48
54
|
|
|
49
55
|
## Estimating tau-squared
|
|
50
56
|
|
|
@@ -63,9 +69,9 @@ Failure to converge raises `ConvergenceError`; it does not silently fall back
|
|
|
63
69
|
to DL.
|
|
64
70
|
|
|
65
71
|
The public default is `tau2_method=None`: it resolves to REML for a random- or
|
|
66
|
-
mixed-effects fit. Common-effect
|
|
67
|
-
supplied tau-squared method so analysis code cannot appear to
|
|
68
|
-
estimator that was not used.
|
|
72
|
+
mixed-effects fit. Common-effect, Mantel-Haenszel, and Peto fits reject an
|
|
73
|
+
explicitly supplied tau-squared method so analysis code cannot appear to
|
|
74
|
+
request an estimator that was not used.
|
|
69
75
|
|
|
70
76
|
## Confidence intervals
|
|
71
77
|
|
|
@@ -89,9 +95,10 @@ cautiously: choosing one does not remove the small-sample uncertainty.
|
|
|
89
95
|
|
|
90
96
|
## Heterogeneity definitions
|
|
91
97
|
|
|
92
|
-
Cochran's Q
|
|
93
|
-
inverse-variance weights
|
|
94
|
-
|
|
98
|
+
Cochran's Q for IV and Mantel-Haenszel fits uses common-effect
|
|
99
|
+
inverse-variance weights; MH residuals are centered on its pooled estimate.
|
|
100
|
+
Peto instead uses its documented observed-minus-expected Q. All common-effect
|
|
101
|
+
fits derive I-squared and H-squared from the applicable Q.
|
|
95
102
|
|
|
96
103
|
For random-effects analyses, I-squared and H-squared instead use the estimated
|
|
97
104
|
tau-squared and a typical within-study variance:
|
|
@@ -50,6 +50,16 @@ Binary analyses record:
|
|
|
50
50
|
- non-informative relative-effect exclusions;
|
|
51
51
|
- a separate Mantel-Haenszel correction record when MH pooling is used.
|
|
52
52
|
|
|
53
|
+
A Peto OR transformation additionally records
|
|
54
|
+
`study_estimator="peto_one_step"`. Its method options state that pooling used
|
|
55
|
+
raw tables and heterogeneity used O-minus-E contributions. The study-level
|
|
56
|
+
continuity-correction record remains separate because it does not alter Peto
|
|
57
|
+
pooling.
|
|
58
|
+
|
|
59
|
+
An MH risk-difference result additionally records
|
|
60
|
+
`mh_rd_variance="Sato-Greenland-Robins"` in its method options, and generated
|
|
61
|
+
Methods text names that variance convention.
|
|
62
|
+
|
|
53
63
|
This separation matters because exact Mantel-Haenszel pooling can use raw
|
|
54
64
|
tables even when a corrected individual effect is needed for display and
|
|
55
65
|
heterogeneity calculations.
|
|
@@ -73,6 +83,8 @@ The text identifies the model, pooling estimator, tau-squared estimator,
|
|
|
73
83
|
confidence interval, heterogeneity statistics, prediction interval,
|
|
74
84
|
correction settings, missing-data policy, numerical controls, and package
|
|
75
85
|
version as applicable.
|
|
86
|
+
For Peto it also names the O-minus-E heterogeneity calculation, raw-table
|
|
87
|
+
pooling, and the estimator's applicability caveat.
|
|
76
88
|
|
|
77
89
|
It is a starting point for a manuscript Methods section. Review and adapt it to
|
|
78
90
|
the analysis protocol, field conventions, and journal requirements.
|
|
@@ -16,6 +16,7 @@ fixtures used by this project.
|
|
|
16
16
|
| Generic effects and variances | `meta_analysis()` | `rma.uni(yi, vi, ...)` | `metagen(TE, seTE, ...)` |
|
|
17
17
|
| Binary 2x2 tables, inverse variance | `meta_binary(..., method="IV")` | `escalc()` then `rma.uni()` | `metabin(..., method="Inverse")` |
|
|
18
18
|
| Binary 2x2 tables, Mantel-Haenszel | `meta_binary(..., method="MH")` | `rma.mh()` | `metabin(..., method="MH")` |
|
|
19
|
+
| Binary 2x2 tables, Peto OR | `meta_binary(..., measure="OR", method="Peto")` | `rma.peto()` | `metabin(..., sm="OR", method="Peto")` |
|
|
19
20
|
| Continuous group summaries | `meta_continuous()` | `escalc()` then `rma.uni()` | `metacont()` |
|
|
20
21
|
| Subgroups | `subgroup=` on a high-level call | separate fits or a moderator model | `subgroup=` |
|
|
21
22
|
| Leave-one-out | `result.leave_one_out()` | `leave1out()` for supported fits | `metainf()` |
|
|
@@ -68,7 +69,8 @@ remain explicit attributes in Python.
|
|
|
68
69
|
| `model="common"` | `rma.uni(..., method="EE")` | `common=TRUE, random=FALSE` | Inverse-variance common-effect fit |
|
|
69
70
|
| `model="random"` | random-effects `rma.uni()` | `random=TRUE` | Requires a tau-squared policy |
|
|
70
71
|
| `method="IV"` | inverse-variance weighting | `method="Inverse"` | Binary API only; generic and continuous fits are IV |
|
|
71
|
-
| `method="MH"` | `rma.mh()` | `method="MH"` | Common-effect OR/RR
|
|
72
|
+
| `method="MH"` | `rma.mh()` | `method="MH"` | Common-effect OR/RR/RD |
|
|
73
|
+
| `method="Peto"` | `rma.peto()` | `method="Peto"` | Common-effect OR; raw pooling tables and O-minus-E heterogeneity |
|
|
72
74
|
| `tau2_method=None` (resolved as `"REML"`) | `method="REML"` | `method.tau="REML"` | PyMetaAnalysis random-effects default |
|
|
73
75
|
| `tau2_method="PM"` | `method="PM"` | `method.tau="PM"` | Paule-Mandel |
|
|
74
76
|
| `tau2_method="DL"` | `method="DL"` | `method.tau="DL"` | DerSimonian-Laird |
|
|
@@ -78,6 +80,9 @@ handling, or heterogeneity definitions. In particular, PyMetaAnalysis records
|
|
|
78
80
|
`i2_method`; random-effects inverse-variance results use the documented
|
|
79
81
|
tau-squared/typical-variance definition, while common-effect and MH results use
|
|
80
82
|
the Q-based definition.
|
|
83
|
+
Peto also reports Q-based inconsistency, but its Q is formed from the Peto
|
|
84
|
+
observed-minus-expected contributions rather than ordinary study-log-OR
|
|
85
|
+
inverse-variance residuals.
|
|
81
86
|
|
|
82
87
|
`result.tau2_confidence_interval()` corresponds to
|
|
83
88
|
`confint(fit, type="QP")` for an `rma.uni` random-effects fit. Both return
|
|
@@ -128,6 +133,19 @@ not implement. For OR/RR, double-zero and double-all studies are excluded from
|
|
|
128
133
|
all model and heterogeneity calculations by default while remaining visible in
|
|
129
134
|
the result table. RD uses its separate `rd_zero_variance` policy.
|
|
130
135
|
|
|
136
|
+
For `measure="RD"`, PyMetaAnalysis and `metafor::rma.mh(measure="RD")` use
|
|
137
|
+
the Sato-Greenland-Robins sampling variance. A separate explicit
|
|
138
|
+
`mh_continuity_correction` changes the MH tables; the study-effect
|
|
139
|
+
`continuity_correction` still affects only displayed study variances and
|
|
140
|
+
heterogeneity.
|
|
141
|
+
|
|
142
|
+
For Peto, PyMetaAnalysis's default study-level correction corresponds to
|
|
143
|
+
`escalc(measure="PETO", add=0.5, to="only0", drop00=TRUE)` for the displayed
|
|
144
|
+
study rows. Its pooled fit corresponds to `rma.peto()` with raw pooling tables;
|
|
145
|
+
the study correction never changes the pooled result. Compare Peto's
|
|
146
|
+
rare-outcome, within-study arm-balance, and modest-effect assumptions before
|
|
147
|
+
porting it solely because a table contains zeros.
|
|
148
|
+
|
|
131
149
|
Read [zero-event studies](zero-events.md) before translating sparse analyses.
|
|
132
150
|
|
|
133
151
|
## Worked generic translation
|
|
@@ -194,6 +212,7 @@ as numerically equivalent.
|
|
|
194
212
|
- [`metafor::rma.uni`](https://wviechtb.github.io/metafor/reference/rma.uni.html)
|
|
195
213
|
- [`metafor::predict.rma`](https://wviechtb.github.io/metafor/reference/predict.rma.html)
|
|
196
214
|
- [`metafor::rma.mh`](https://wviechtb.github.io/metafor/reference/rma.mh.html)
|
|
215
|
+
- [`metafor::rma.peto`](https://wviechtb.github.io/metafor/reference/rma.peto.html)
|
|
197
216
|
- [`metafor::escalc`](https://wviechtb.github.io/metafor/reference/escalc.html)
|
|
198
217
|
- [`meta::metagen`](https://search.r-project.org/CRAN/refmans/meta/html/metagen.html)
|
|
199
218
|
- [`meta::metabin`](https://search.r-project.org/CRAN/refmans/meta/html/metabin.html)
|
|
@@ -160,7 +160,7 @@ model, and the boundary is recorded in `cumulative.warnings`.
|
|
|
160
160
|
Every refit reuses the original result's:
|
|
161
161
|
|
|
162
162
|
- common- or random-effects model;
|
|
163
|
-
- inverse-variance
|
|
163
|
+
- inverse-variance, Mantel-Haenszel, or Peto pooling method;
|
|
164
164
|
- tau-squared and confidence-interval methods;
|
|
165
165
|
- confidence level, absolute tolerance, and iteration limit;
|
|
166
166
|
- missing-data policy;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Zero-event studies
|
|
2
2
|
|
|
3
|
-
Zero cells in 2-by-2 tables affect OR, RR, RD,
|
|
4
|
-
different ways. PyMetaAnalysis therefore separates study-level
|
|
5
|
-
corrections from
|
|
3
|
+
Zero cells in 2-by-2 tables affect OR, RR, RD, Mantel-Haenszel, and Peto
|
|
4
|
+
estimators in different ways. PyMetaAnalysis therefore separates study-level
|
|
5
|
+
effect corrections from table-based pooling rules.
|
|
6
6
|
|
|
7
7
|
## Default study-level correction
|
|
8
8
|
|
|
@@ -71,7 +71,8 @@ RD-specific; setting `exclude` for OR or RR is rejected.
|
|
|
71
71
|
|
|
72
72
|
## Mantel-Haenszel correction is separate
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
Uncorrected common-effect Mantel-Haenszel OR/RR/RD pooling uses raw tables by
|
|
75
|
+
default:
|
|
75
76
|
|
|
76
77
|
```python
|
|
77
78
|
mh_continuity_correction = None
|
|
@@ -83,6 +84,29 @@ and heterogeneity. It does not silently alter the pooled Mantel-Haenszel
|
|
|
83
84
|
estimator. If an exact pooled estimator is undefined, choose an explicit
|
|
84
85
|
positive `mh_continuity_correction` and report that decision.
|
|
85
86
|
|
|
87
|
+
For MH RD, `rd_zero_variance="exclude"` removes zero-variance boundary rows
|
|
88
|
+
before every synthesis calculation. With the default `"correct"` policy, the
|
|
89
|
+
raw table still enters the MH point estimate unless an explicit
|
|
90
|
+
`mh_continuity_correction` is supplied. If the Sato-Greenland-Robins variance
|
|
91
|
+
is non-positive, the uncorrected fit raises instead of silently changing the
|
|
92
|
+
tables; a positive MH correction is an explicit protocol choice.
|
|
93
|
+
|
|
94
|
+
## Peto pooling always uses raw tables
|
|
95
|
+
|
|
96
|
+
Peto's observed-minus-expected pooling contribution remains defined for many
|
|
97
|
+
single-zero tables, so `method="Peto"` does not apply a continuity correction
|
|
98
|
+
to pooling or Peto Q. The general `continuity_correction` and
|
|
99
|
+
`correction_scope` settings apply only to the one-step study effects and
|
|
100
|
+
variances shown in the study table. There is deliberately no separate Peto
|
|
101
|
+
pooling-correction option.
|
|
102
|
+
|
|
103
|
+
Double-zero and double-all studies have zero Peto information and are excluded
|
|
104
|
+
before pooling, Q, I-squared, H-squared, and weights. The result retains the
|
|
105
|
+
same structured exclusion reasons used for other relative-effect analyses.
|
|
106
|
+
Peto's lack of a single-zero pooling correction does not make it universally
|
|
107
|
+
preferable: its rare-outcome, balanced-arm, and modest-effect assumptions must
|
|
108
|
+
still be considered.
|
|
109
|
+
|
|
86
110
|
## Inspect what happened
|
|
87
111
|
|
|
88
112
|
```python
|
|
@@ -104,3 +128,5 @@ Resolved correction values and scopes also appear in
|
|
|
104
128
|
zero-variance policy and affected row IDs in provenance. This makes it possible
|
|
105
129
|
to distinguish a corrected analysis from an exact or exclusion-based one after
|
|
106
130
|
fitting.
|
|
131
|
+
Peto analyses additionally record `peto_pooling_tables="raw"` and
|
|
132
|
+
`peto_heterogeneity="O-minus-E"`.
|
|
@@ -84,11 +84,13 @@ lists unsupported methods explicitly.
|
|
|
84
84
|
|
|
85
85
|
## Project status
|
|
86
86
|
|
|
87
|
-
PyMetaAnalysis 0.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
PyMetaAnalysis 0.6.0 adds common-effect Mantel-Haenszel risk-difference and
|
|
88
|
+
Peto one-step odds-ratio pooling, with explicit sparse-table policies,
|
|
89
|
+
statistical metadata, and independent R references. It also retains the
|
|
90
|
+
Q-profile heterogeneity intervals and Meta-regression diagnostics introduced
|
|
91
|
+
in earlier releases. The project has not undergone a formal external
|
|
92
|
+
statistical audit. Pin the package version for consequential work and
|
|
93
|
+
independently check important analyses. See the
|
|
92
94
|
repository
|
|
93
95
|
[changelog](https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/CHANGELOG.md)
|
|
94
96
|
and [contribution guide](development.md). For manuscripts and archived
|