PyMetaAnalysis 0.3.0__tar.gz → 0.5.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.3.0 → pymetaanalysis-0.5.0}/.github/workflows/ci.yml +1 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/.github/workflows/pages.yml +1 -2
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/.github/workflows/release.yml +7 -3
- pymetaanalysis-0.5.0/CHANGELOG.md +187 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/CITATION.cff +2 -2
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/PKG-INFO +35 -7
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/README.md +32 -5
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/adr/0002-statistical-policy.md +7 -4
- pymetaanalysis-0.5.0/docs/adr/0003-meta-regression-prediction-intervals.md +70 -0
- pymetaanalysis-0.5.0/docs/adr/0004-hartung-knapp-prediction-intervals.md +46 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/getting-started.md +1 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/input-data.md +18 -2
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/meta-regression.md +153 -3
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/method-selection.md +55 -4
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/r-interoperability.md +26 -4
- pymetaanalysis-0.5.0/docs/guides/sensitivity-analysis.md +198 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/zero-events.md +19 -8
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/index.md +6 -5
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/limitations.md +19 -6
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/methods/statistical-methods.md +208 -18
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/reference/api.md +46 -16
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/reference/report-schema.md +2 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/reference/results.md +188 -9
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/releasing.md +14 -9
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/validation.md +57 -13
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/mkdocs.yml +2 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/pyproject.toml +2 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/__init__.py +16 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/_version.py +1 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/api.py +65 -17
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/binary_api.py +30 -12
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/continuous_api.py +37 -16
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/data.py +40 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/design_matrix.py +80 -21
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/effect_sizes/binary.py +60 -19
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/effect_sizes/continuous.py +34 -4
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/estimators/inverse_variance.py +22 -6
- pymetaanalysis-0.5.0/src/meta_analyze/estimators/mantel_haenszel.py +140 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/estimators/meta_regression.py +117 -34
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/estimators/tau2.py +42 -20
- pymetaanalysis-0.5.0/src/meta_analyze/heterogeneity.py +285 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/plotting/_utils.py +10 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/plotting/forest.py +24 -5
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/plotting/subgroup_forest.py +32 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/regression_api.py +56 -9
- pymetaanalysis-0.5.0/src/meta_analyze/regression_collinearity.py +285 -0
- pymetaanalysis-0.5.0/src/meta_analyze/regression_contrasts.py +365 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/regression_results.py +115 -1
- pymetaanalysis-0.5.0/src/meta_analyze/regression_sensitivity.py +563 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/reporting.py +28 -16
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/results.py +170 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/sensitivity.py +115 -33
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/subgroups.py +61 -12
- pymetaanalysis-0.5.0/tests/reference/README.md +77 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/binary_metafor.json +12 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generate_binary_metafor.R +17 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generate_generic_metafor.R +32 -8
- pymetaanalysis-0.5.0/tests/reference/generate_meta_regression_collinearity_metafor.R +81 -0
- pymetaanalysis-0.5.0/tests/reference/generate_meta_regression_contrasts_metafor.R +96 -0
- pymetaanalysis-0.5.0/tests/reference/generate_meta_regression_influence_metafor.R +95 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generate_meta_regression_metafor.R +122 -9
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generate_workflow_metafor.R +10 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generic_metafor.json +27 -1
- pymetaanalysis-0.5.0/tests/reference/meta_regression_collinearity_metafor.json +65 -0
- pymetaanalysis-0.5.0/tests/reference/meta_regression_contrasts_metafor.json +157 -0
- pymetaanalysis-0.5.0/tests/reference/meta_regression_influence_metafor.json +1131 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/meta_regression_metafor.json +395 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/workflow_metafor.json +6 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_api.py +236 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_binary.py +92 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_continuous.py +41 -0
- pymetaanalysis-0.5.0/tests/test_estimators.py +350 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_funnel_plot.py +1 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_meta_regression.py +160 -1
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_numerical_stability.py +128 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_plotting.py +11 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_properties.py +85 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_r_references.py +271 -5
- pymetaanalysis-0.5.0/tests/test_regression_collinearity.py +288 -0
- pymetaanalysis-0.5.0/tests/test_regression_contrasts.py +346 -0
- pymetaanalysis-0.5.0/tests/test_regression_influence.py +362 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_regression_plotting.py +1 -1
- pymetaanalysis-0.5.0/tests/test_regression_sensitivity.py +298 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_release_readiness.py +39 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_reporting.py +5 -4
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_sensitivity.py +84 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_subgroups.py +102 -8
- pymetaanalysis-0.3.0/CHANGELOG.md +0 -88
- pymetaanalysis-0.3.0/docs/guides/sensitivity-analysis.md +0 -108
- pymetaanalysis-0.3.0/src/meta_analyze/estimators/mantel_haenszel.py +0 -101
- pymetaanalysis-0.3.0/src/meta_analyze/heterogeneity.py +0 -99
- pymetaanalysis-0.3.0/tests/reference/README.md +0 -51
- pymetaanalysis-0.3.0/tests/test_estimators.py +0 -147
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/.gitignore +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/CONTRIBUTING.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/LICENSE +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/SECURITY.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/benchmarks/README.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/benchmarks/benchmark_core.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/adr/0001-optional-matplotlib.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/citation.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/development.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/binary-outcomes.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/continuous-outcomes.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/generic-effects.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/plotting.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/guides/provenance-reporting.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/installation.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/docs/stylesheets/extra.css +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/examples/README.md +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/examples/meta_regression.ipynb +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/examples/quickstart.ipynb +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/config.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/effect_sizes/__init__.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/estimators/__init__.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/exceptions.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/plotting/__init__.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/plotting/funnel.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/plotting/regression.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/provenance.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/src/meta_analyze/py.typed +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/binary_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/binary_sparse_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/continuous_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/continuous_metafor.json +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generate_continuous_metafor.R +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/generic_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/meta_regression_boundary_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/meta_regression_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/reference/workflow_input.csv +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_documentation.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tests/test_reference_results.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tools/check_release.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tools/execute_notebooks.py +0 -0
- {pymetaanalysis-0.3.0 → pymetaanalysis-0.5.0}/tools/inspect_distribution.py +0 -0
|
@@ -8,7 +8,7 @@ on:
|
|
|
8
8
|
|
|
9
9
|
concurrency:
|
|
10
10
|
group: pages
|
|
11
|
-
cancel-in-progress:
|
|
11
|
+
cancel-in-progress: false
|
|
12
12
|
|
|
13
13
|
jobs:
|
|
14
14
|
build:
|
|
@@ -17,7 +17,6 @@ jobs:
|
|
|
17
17
|
timeout-minutes: 10
|
|
18
18
|
permissions:
|
|
19
19
|
contents: read
|
|
20
|
-
pages: write
|
|
21
20
|
|
|
22
21
|
steps:
|
|
23
22
|
- name: Check out repository
|
|
@@ -35,14 +35,17 @@ jobs:
|
|
|
35
35
|
cache: pip
|
|
36
36
|
cache-dependency-path: pyproject.toml
|
|
37
37
|
|
|
38
|
-
- name: Install
|
|
38
|
+
- name: Install release dependencies
|
|
39
39
|
run: |
|
|
40
40
|
python -m pip install --upgrade pip
|
|
41
|
-
python -m pip install build twine
|
|
41
|
+
python -m pip install ".[test]" build twine
|
|
42
42
|
|
|
43
43
|
- name: Validate release metadata
|
|
44
44
|
run: python tools/check_release.py --tag "$GITHUB_REF_NAME"
|
|
45
45
|
|
|
46
|
+
- name: Run tests with branch coverage
|
|
47
|
+
run: python -m pytest --cov=meta_analyze --cov-branch --cov-report=term-missing
|
|
48
|
+
|
|
46
49
|
- name: Build distributions
|
|
47
50
|
run: python -m build
|
|
48
51
|
|
|
@@ -91,7 +94,8 @@ jobs:
|
|
|
91
94
|
path: dist/
|
|
92
95
|
|
|
93
96
|
- name: Publish to PyPI
|
|
94
|
-
|
|
97
|
+
# release/v1.14, pinned because this step holds the PyPI OIDC permission.
|
|
98
|
+
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247
|
|
95
99
|
|
|
96
100
|
github-release:
|
|
97
101
|
name: Create GitHub Release
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to PyMetaAnalysis will be documented in this file.
|
|
4
|
+
|
|
5
|
+
Changes planned for the next release accumulate under `Unreleased`.
|
|
6
|
+
|
|
7
|
+
## Unreleased
|
|
8
|
+
|
|
9
|
+
## 0.5.0 - 2026-07-25
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- random-effects inverse-variance results now provide opt-in Q-profile
|
|
14
|
+
confidence intervals for tau-squared, tau, I-squared, and H-squared, with an
|
|
15
|
+
explicit formal-empty-set flag at the constrained `[0, 0]` boundary.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- sensitivity and influence workflows now borrow internal fitted buffers during
|
|
20
|
+
refits instead of repeatedly materializing public defensive copies;
|
|
21
|
+
- Meta-regression stores its classic coefficient covariance alongside the
|
|
22
|
+
selected inference covariance and reuses one shared precision-geometry
|
|
23
|
+
implementation across fitting and diagnostics.
|
|
24
|
+
- independent `metafor` fixtures now cover categorical and multivariable
|
|
25
|
+
influence diagnostics, no-intercept Riley prediction intervals, and explicit
|
|
26
|
+
Mantel-Haenszel pooling correction; iterative failure paths have direct
|
|
27
|
+
regression tests.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- inverse-variance means, heterogeneity statistics, and pooling and
|
|
32
|
+
meta-regression tau-squared equations now use overflow-safe relative-weight
|
|
33
|
+
calculations at the supported float64 boundary;
|
|
34
|
+
- subnormal variances and non-finite derived effects now raise explicit domain
|
|
35
|
+
errors instead of leaking runtime warnings or returning invalid results;
|
|
36
|
+
- binary OR, RD, and Mantel-Haenszel arithmetic now avoids intermediate
|
|
37
|
+
overflow for very large finite counts;
|
|
38
|
+
- the sensitivity guide no longer incorrectly states that Meta-regression
|
|
39
|
+
Cook's distance and DFBETAS are unavailable.
|
|
40
|
+
- subgroup-differences tests now use classic model variances independently of
|
|
41
|
+
Hartung-Knapp confidence-interval adjustments;
|
|
42
|
+
- leave-one-out and cumulative workflows now retain or skip, respectively,
|
|
43
|
+
reduced Mantel-Haenszel fits that are not estimable instead of aborting the
|
|
44
|
+
complete sensitivity analysis;
|
|
45
|
+
- forest and subgroup-forest plots now reject non-positive displayed
|
|
46
|
+
coordinates before enabling a logarithmic axis;
|
|
47
|
+
- uncorrected risk-ratio analyses now accept a zero non-event cell when the
|
|
48
|
+
study effect and sampling variance remain well defined.
|
|
49
|
+
- Hartung-Knapp random-effects prediction intervals now use the selected
|
|
50
|
+
adjusted pooled-mean variance and are recorded as `HK-PR`, matching
|
|
51
|
+
`metafor` Riley predictions;
|
|
52
|
+
- random-effects subgroup analyses now retain single-study subgroups through
|
|
53
|
+
an explicit, warned common-effect fallback instead of failing the complete
|
|
54
|
+
analysis;
|
|
55
|
+
- tagged releases now rerun the full branch-coverage test suite before
|
|
56
|
+
distributions can be built and published.
|
|
57
|
+
- tau-squared methods and SMD variance conventions now use `None` as the
|
|
58
|
+
context-sensitive default, so explicitly inapplicable settings raise domain
|
|
59
|
+
errors instead of being silently ignored;
|
|
60
|
+
- duplicate study labels now add a row-position warning while preserving
|
|
61
|
+
`row_id` as the unique audit key;
|
|
62
|
+
- report JSON now serializes `pd.NaT` study labels as `null` rather than the
|
|
63
|
+
string `"NaT"`.
|
|
64
|
+
- Meta-regression with `missing="drop"` now determines complete-row exclusions
|
|
65
|
+
before validating moderator values, so invalid values in already excluded
|
|
66
|
+
rows cannot abort the analysis;
|
|
67
|
+
- cumulative analysis now rejects ambiguous string `order` selectors that
|
|
68
|
+
exist in both source data and study results;
|
|
69
|
+
- empty inputs now report that at least one study row is required, and binary
|
|
70
|
+
zero-cell errors identify when `correction_scope="none"` disables an
|
|
71
|
+
otherwise positive correction.
|
|
72
|
+
- iterative tau-squared estimators now mark only an exact constrained zero as
|
|
73
|
+
a boundary solution, rather than treating every positive root below `atol`
|
|
74
|
+
as zero;
|
|
75
|
+
- the exported pooling and Meta-regression tau-squared estimators now reject
|
|
76
|
+
insufficient study or residual degrees of freedom with domain-specific
|
|
77
|
+
errors;
|
|
78
|
+
- the Mantel-Haenszel estimator now rejects empty and zero-total strata before
|
|
79
|
+
division, preventing NaN propagation and misleading variance diagnostics.
|
|
80
|
+
- prediction-interval metadata is now `None` when too few studies prevent an
|
|
81
|
+
interval from being calculated;
|
|
82
|
+
- categorical moderator encoding no longer conflates booleans, integers, and
|
|
83
|
+
floating-point values through Python's cross-type numeric equality;
|
|
84
|
+
- CI now covers Python 3.14, Pages deployments are not cancelled mid-flight,
|
|
85
|
+
and the credential-bearing PyPI publisher action is pinned to an immutable
|
|
86
|
+
commit.
|
|
87
|
+
|
|
88
|
+
## 0.4.0 - 2026-07-23
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- leave-one-out Meta-regression refits with model-level diagnostics,
|
|
93
|
+
coefficient changes, explicit unidentifiable-deletion records, and preserved
|
|
94
|
+
provenance.
|
|
95
|
+
- exact Meta-regression externally standardized residuals, Cook's distances,
|
|
96
|
+
DFBETAS, transparent screening thresholds, and fixed-version R `metafor`
|
|
97
|
+
cross-software fixtures.
|
|
98
|
+
- Meta-regression term VIF, moderator-level GVIF/GSIF, and weighted,
|
|
99
|
+
column-scaled condition diagnostics with variance-decomposition proportions,
|
|
100
|
+
heuristic-only flags, and R `metafor` cross-software fixtures.
|
|
101
|
+
- explicit named Meta-regression linear contrasts with nonzero null values,
|
|
102
|
+
individual z/t inference, joint chi-squared/F tests, labeled coefficient
|
|
103
|
+
matrices, and R `metafor` cross-software fixtures.
|
|
104
|
+
- opt-in Riley Meta-regression true-effect prediction intervals using
|
|
105
|
+
`t_(k-p-1)`, with explicit residual-df validation, preserved refit
|
|
106
|
+
configuration, and fixed-version R `metafor` boundary references.
|
|
107
|
+
|
|
108
|
+
## 0.3.0 - 2026-07-22
|
|
109
|
+
|
|
110
|
+
### Added
|
|
111
|
+
|
|
112
|
+
- pandas-first `meta_regression()` for numeric, explicitly encoded categorical,
|
|
113
|
+
and multiple study-level moderators;
|
|
114
|
+
- common- and mixed-effects weighted regression with generalized DL, PM, and
|
|
115
|
+
REML residual tau-squared estimators;
|
|
116
|
+
- normal, Hartung-Knapp, and safeguarded Hartung-Knapp coefficient inference,
|
|
117
|
+
distribution-explicit moderator tests, residual heterogeneity, pseudo-R²,
|
|
118
|
+
prediction, provenance, and structured reports;
|
|
119
|
+
- optional weighted bubble plots for intercept-containing Meta-regression fits
|
|
120
|
+
with exactly one numeric moderator;
|
|
121
|
+
- independent R `metafor` fixtures covering numeric, categorical,
|
|
122
|
+
multivariable, zero-tau-squared, missing-row, and small-sample cases;
|
|
123
|
+
- an executable Meta-regression notebook plus a multivariable performance
|
|
124
|
+
baseline and expanded property, numerical-stability, and warning tests.
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
|
|
128
|
+
- report schema 1.2 adds the `meta_regression` report type.
|
|
129
|
+
|
|
130
|
+
## 0.2.1 - 2026-07-17
|
|
131
|
+
|
|
132
|
+
### Fixed
|
|
133
|
+
|
|
134
|
+
- README documentation and repository links use absolute URLs so they resolve
|
|
135
|
+
correctly when the project description is rendered on PyPI.
|
|
136
|
+
|
|
137
|
+
## 0.2.0 - 2026-07-16
|
|
138
|
+
|
|
139
|
+
### Added
|
|
140
|
+
|
|
141
|
+
- generic `meta_analysis()` accepts either sampling variances or standard
|
|
142
|
+
errors, with explicit validation and auditable conversion provenance.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- package author metadata identifies the project maintainer directly.
|
|
147
|
+
|
|
148
|
+
### Fixed
|
|
149
|
+
|
|
150
|
+
- GitHub Release creation receives explicit repository context in tag-driven
|
|
151
|
+
release jobs.
|
|
152
|
+
|
|
153
|
+
## 0.1.0 - 2026-07-15
|
|
154
|
+
|
|
155
|
+
### Added
|
|
156
|
+
|
|
157
|
+
- pandas-first generic, binary, and continuous study-level meta-analysis APIs;
|
|
158
|
+
- common-effect and random-effects inverse-variance models;
|
|
159
|
+
- common-effect Mantel-Haenszel OR/RR pooling;
|
|
160
|
+
- REML, Paule-Mandel, and DerSimonian-Laird tau-squared estimators;
|
|
161
|
+
- normal, Hartung-Knapp, and safeguarded Hartung-Knapp confidence intervals;
|
|
162
|
+
- HTS random-effects prediction intervals;
|
|
163
|
+
- subgroup, leave-one-out, and cumulative workflows;
|
|
164
|
+
- optional Matplotlib forest, subgroup forest, and funnel plots;
|
|
165
|
+
- immutable results, diagnostics, provenance, Methods text, and JSON/Markdown
|
|
166
|
+
reports;
|
|
167
|
+
- R `metafor` cross-software fixtures, property tests, and numerical edge-case
|
|
168
|
+
coverage;
|
|
169
|
+
- explicit RD zero-variance boundary policy and heterogeneity-definition
|
|
170
|
+
reporting;
|
|
171
|
+
- complete MkDocs user, methods, API, validation, limitation, and development
|
|
172
|
+
documentation;
|
|
173
|
+
- R `meta`/`metafor` terminology and parameter mappings;
|
|
174
|
+
- machine-readable citation metadata and an executable end-to-end notebook;
|
|
175
|
+
- GitHub Pages and PyPI Trusted Publishing release workflows;
|
|
176
|
+
- release metadata, distribution-content, notebook-execution, and performance
|
|
177
|
+
baseline tooling.
|
|
178
|
+
|
|
179
|
+
### Changed
|
|
180
|
+
|
|
181
|
+
- independent external statistical review is documented as a recommended
|
|
182
|
+
validation activity rather than a release requirement;
|
|
183
|
+
- report schema 1.1 records `heterogeneity.i2_method`;
|
|
184
|
+
- random-effects I-squared/H-squared use tau-squared and typical within-study
|
|
185
|
+
variance, while common-effect/MH analyses retain Q-based definitions;
|
|
186
|
+
- random-effects summaries provide method-selection notes for small-study and
|
|
187
|
+
positive-heterogeneity cases.
|
|
@@ -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-07-
|
|
11
|
+
version: 0.5.0
|
|
12
|
+
date-released: 2026-07-25
|
|
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.5.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
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
22
|
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
22
23
|
Requires-Python: >=3.10
|
|
23
24
|
Requires-Dist: numpy>=1.24
|
|
@@ -28,7 +29,7 @@ Requires-Dist: actionlint-py>=1.7.12.24; extra == 'dev'
|
|
|
28
29
|
Requires-Dist: build>=1.2; extra == 'dev'
|
|
29
30
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
30
31
|
Requires-Dist: pandas-stubs>=2.0; extra == 'dev'
|
|
31
|
-
Requires-Dist: ruff
|
|
32
|
+
Requires-Dist: ruff<0.17,>=0.16; extra == 'dev'
|
|
32
33
|
Requires-Dist: scipy-stubs>=1.10; extra == 'dev'
|
|
33
34
|
Provides-Extra: docs
|
|
34
35
|
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
@@ -139,7 +140,10 @@ not individual-level or causal effects.
|
|
|
139
140
|
Random-effects inverse-variance models support REML (default), Paule-Mandel,
|
|
140
141
|
and DerSimonian-Laird tau-squared estimators. Mean confidence intervals support
|
|
141
142
|
the normal default plus unmodified and safeguarded Hartung-Knapp variants.
|
|
142
|
-
Eligible random-effects fits include an HTS prediction interval
|
|
143
|
+
Eligible random-effects fits include an HTS prediction interval under normal
|
|
144
|
+
inference and an HK-PR interval under either Hartung-Knapp variant. Call
|
|
145
|
+
`result.tau2_confidence_interval()` for a Q-profile interval around
|
|
146
|
+
heterogeneity.
|
|
143
147
|
|
|
144
148
|
Generic analyses accept exactly one of `variance=` or `standard_error=`.
|
|
145
149
|
Standard errors are squared internally and the conversion is recorded in the
|
|
@@ -157,6 +161,7 @@ result.estimate
|
|
|
157
161
|
result.display_estimate
|
|
158
162
|
result.ci
|
|
159
163
|
result.tau2
|
|
164
|
+
tau2_interval = result.tau2_confidence_interval()
|
|
160
165
|
result.i2
|
|
161
166
|
result.i2_method
|
|
162
167
|
result.diagnostics
|
|
@@ -177,11 +182,23 @@ Rows excluded by missing-value or sparse-data policies remain in
|
|
|
177
182
|
`study_results` with a stable `row_id`, `included=False`, and an
|
|
178
183
|
`exclusion_reason`.
|
|
179
184
|
|
|
180
|
-
##
|
|
185
|
+
## Diagnostics, contrasts, and plots
|
|
181
186
|
|
|
182
187
|
```python
|
|
183
188
|
leave_one_out = result.leave_one_out().to_dataframe()
|
|
184
189
|
cumulative = result.cumulative(order="publication_year").to_dataframe()
|
|
190
|
+
regression_deleted = regression.leave_one_out()
|
|
191
|
+
regression_coefficient_changes = regression_deleted.coefficients
|
|
192
|
+
regression_influence = regression.influence()
|
|
193
|
+
flagged_diagnostics = regression_influence.flagged
|
|
194
|
+
collinearity = regression.collinearity()
|
|
195
|
+
term_vif = collinearity.term_vif
|
|
196
|
+
moderator_gvif = collinearity.moderator_gvif
|
|
197
|
+
condition_indices = collinearity.condition_indices
|
|
198
|
+
south_vs_east = regression.contrast(
|
|
199
|
+
{"region[South]": 1.0, "region[East]": -1.0},
|
|
200
|
+
name="South - East",
|
|
201
|
+
)
|
|
185
202
|
|
|
186
203
|
ax = result.forest(show_prediction_interval=True)
|
|
187
204
|
ax = result.funnel()
|
|
@@ -189,9 +206,20 @@ ax = result.funnel()
|
|
|
189
206
|
|
|
190
207
|
Plotting methods return Matplotlib axes and never call `show()`. Funnel plots
|
|
191
208
|
are descriptive small-study-effect diagnostics, not proof of publication bias.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
209
|
+
Meta-regression leave-one-out results also expose a long-form coefficient
|
|
210
|
+
change table. Exact influence diagnostics add externally standardized
|
|
211
|
+
residuals, Cook's distance, DFBETAS, and explicit heuristic screening
|
|
212
|
+
thresholds without automatically excluding studies. Meta-regression
|
|
213
|
+
collinearity diagnostics add `metafor`-compatible VIF/GVIF plus weighted,
|
|
214
|
+
column-scaled condition indices and variance-decomposition proportions.
|
|
215
|
+
Their documented references are review aids, not automatic variable-selection
|
|
216
|
+
rules. Explicit named linear contrasts provide individual z/t inference and
|
|
217
|
+
full-rank joint chi-squared/F tests without silently adjusting for multiple
|
|
218
|
+
testing. An eligible
|
|
219
|
+
single-numeric-moderator Meta-regression result additionally provides
|
|
220
|
+
`regression.bubble()` with fitted confidence and optional prediction bands.
|
|
221
|
+
Mixed-effects Meta-regression supports its documented default prediction rule
|
|
222
|
+
and an explicit Riley `t_(k-p-1)` alternative.
|
|
195
223
|
|
|
196
224
|
## Documentation
|
|
197
225
|
|
|
@@ -90,7 +90,10 @@ not individual-level or causal effects.
|
|
|
90
90
|
Random-effects inverse-variance models support REML (default), Paule-Mandel,
|
|
91
91
|
and DerSimonian-Laird tau-squared estimators. Mean confidence intervals support
|
|
92
92
|
the normal default plus unmodified and safeguarded Hartung-Knapp variants.
|
|
93
|
-
Eligible random-effects fits include an HTS prediction interval
|
|
93
|
+
Eligible random-effects fits include an HTS prediction interval under normal
|
|
94
|
+
inference and an HK-PR interval under either Hartung-Knapp variant. Call
|
|
95
|
+
`result.tau2_confidence_interval()` for a Q-profile interval around
|
|
96
|
+
heterogeneity.
|
|
94
97
|
|
|
95
98
|
Generic analyses accept exactly one of `variance=` or `standard_error=`.
|
|
96
99
|
Standard errors are squared internally and the conversion is recorded in the
|
|
@@ -108,6 +111,7 @@ result.estimate
|
|
|
108
111
|
result.display_estimate
|
|
109
112
|
result.ci
|
|
110
113
|
result.tau2
|
|
114
|
+
tau2_interval = result.tau2_confidence_interval()
|
|
111
115
|
result.i2
|
|
112
116
|
result.i2_method
|
|
113
117
|
result.diagnostics
|
|
@@ -128,11 +132,23 @@ Rows excluded by missing-value or sparse-data policies remain in
|
|
|
128
132
|
`study_results` with a stable `row_id`, `included=False`, and an
|
|
129
133
|
`exclusion_reason`.
|
|
130
134
|
|
|
131
|
-
##
|
|
135
|
+
## Diagnostics, contrasts, and plots
|
|
132
136
|
|
|
133
137
|
```python
|
|
134
138
|
leave_one_out = result.leave_one_out().to_dataframe()
|
|
135
139
|
cumulative = result.cumulative(order="publication_year").to_dataframe()
|
|
140
|
+
regression_deleted = regression.leave_one_out()
|
|
141
|
+
regression_coefficient_changes = regression_deleted.coefficients
|
|
142
|
+
regression_influence = regression.influence()
|
|
143
|
+
flagged_diagnostics = regression_influence.flagged
|
|
144
|
+
collinearity = regression.collinearity()
|
|
145
|
+
term_vif = collinearity.term_vif
|
|
146
|
+
moderator_gvif = collinearity.moderator_gvif
|
|
147
|
+
condition_indices = collinearity.condition_indices
|
|
148
|
+
south_vs_east = regression.contrast(
|
|
149
|
+
{"region[South]": 1.0, "region[East]": -1.0},
|
|
150
|
+
name="South - East",
|
|
151
|
+
)
|
|
136
152
|
|
|
137
153
|
ax = result.forest(show_prediction_interval=True)
|
|
138
154
|
ax = result.funnel()
|
|
@@ -140,9 +156,20 @@ ax = result.funnel()
|
|
|
140
156
|
|
|
141
157
|
Plotting methods return Matplotlib axes and never call `show()`. Funnel plots
|
|
142
158
|
are descriptive small-study-effect diagnostics, not proof of publication bias.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
159
|
+
Meta-regression leave-one-out results also expose a long-form coefficient
|
|
160
|
+
change table. Exact influence diagnostics add externally standardized
|
|
161
|
+
residuals, Cook's distance, DFBETAS, and explicit heuristic screening
|
|
162
|
+
thresholds without automatically excluding studies. Meta-regression
|
|
163
|
+
collinearity diagnostics add `metafor`-compatible VIF/GVIF plus weighted,
|
|
164
|
+
column-scaled condition indices and variance-decomposition proportions.
|
|
165
|
+
Their documented references are review aids, not automatic variable-selection
|
|
166
|
+
rules. Explicit named linear contrasts provide individual z/t inference and
|
|
167
|
+
full-rank joint chi-squared/F tests without silently adjusting for multiple
|
|
168
|
+
testing. An eligible
|
|
169
|
+
single-numeric-moderator Meta-regression result additionally provides
|
|
170
|
+
`regression.bubble()` with fitted confidence and optional prediction bands.
|
|
171
|
+
Mixed-effects Meta-regression supports its documented default prediction rule
|
|
172
|
+
and an explicit Riley `t_(k-p-1)` alternative.
|
|
146
173
|
|
|
147
174
|
## Documentation
|
|
148
175
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
- Status: Accepted
|
|
4
4
|
- Date: 2026-07-15
|
|
5
|
+
- Amendment: the prediction-interval variance decision is superseded by
|
|
6
|
+
[ADR 0004](0004-hartung-knapp-prediction-intervals.md).
|
|
5
7
|
|
|
6
8
|
## Context
|
|
7
9
|
|
|
@@ -65,10 +67,11 @@ percentage in human-readable output.
|
|
|
65
67
|
|
|
66
68
|
### Prediction intervals
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
The original decision used the Higgins-Thompson-Spiegelhalter prediction
|
|
71
|
+
interval with `k - 2` degrees of freedom and the classic variance of the
|
|
72
|
+
pooled mean for every confidence-interval method. ADR 0004 replaces that
|
|
73
|
+
variance rule for Hartung-Knapp fits while retaining the study-count boundary
|
|
74
|
+
and small-sample warning.
|
|
72
75
|
|
|
73
76
|
## Validation
|
|
74
77
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# ADR 0003: Meta-regression prediction-interval choices
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-23
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
For a mixed-effects Meta-regression prediction at design vector `x`, the
|
|
9
|
+
estimated true-effect variance combines residual heterogeneity with
|
|
10
|
+
uncertainty in the fitted mean:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
Var_prediction = tau^2 + x' Cov(beta_hat) x
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The critical-value distribution remains a methodological choice. Common
|
|
17
|
+
software offers a default normal-or-t rule and a Riley alternative with one
|
|
18
|
+
fewer residual degree of freedom. Neither approximation removes uncertainty
|
|
19
|
+
from estimating tau-squared, and changing the package default would alter
|
|
20
|
+
existing results.
|
|
21
|
+
|
|
22
|
+
## Decision
|
|
23
|
+
|
|
24
|
+
`meta_regression()` accepts
|
|
25
|
+
`prediction_interval_method="default" | "riley"` for mixed-effects models.
|
|
26
|
+
The canonical resolved method is stored in
|
|
27
|
+
`result.method.prediction_interval_method`.
|
|
28
|
+
|
|
29
|
+
The default remains `normal_or_t_k_minus_p`:
|
|
30
|
+
|
|
31
|
+
- normal coefficient inference uses a standard normal prediction critical
|
|
32
|
+
value;
|
|
33
|
+
- either Hartung-Knapp mode uses a t critical value with `k-p` degrees of
|
|
34
|
+
freedom.
|
|
35
|
+
|
|
36
|
+
The opt-in Riley method uses a t critical value with `k-p-1` degrees of
|
|
37
|
+
freedom regardless of the coefficient-inference distribution:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
prediction = x' beta_hat
|
|
41
|
+
PI_Riley = prediction +/- t_(k-p-1) *
|
|
42
|
+
sqrt(tau^2 + x' Cov(beta_hat) x)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Riley intervals require `k-p >= 2`. Requesting Riley for a common-effect model
|
|
46
|
+
or a mixed model without enough residual degrees of freedom raises a domain
|
|
47
|
+
error. The selection is preserved by deleted-study refits and reused by
|
|
48
|
+
`predict()` and `bubble()`.
|
|
49
|
+
|
|
50
|
+
Both rules predict the distribution of true effects in a new study at the
|
|
51
|
+
specified moderator values. They do not add an unknown sampling variance for
|
|
52
|
+
a future observed effect.
|
|
53
|
+
|
|
54
|
+
## Validation
|
|
55
|
+
|
|
56
|
+
The committed fixed-version R `metafor` fixture records default and
|
|
57
|
+
`predtype="Riley"` predictions for normal and Hartung-Knapp inference,
|
|
58
|
+
multivariable moderator values, and a zero-tau-squared boundary. Unit tests
|
|
59
|
+
also check the critical-value formula and invalid degrees of freedom.
|
|
60
|
+
Property-based tests verify symmetry, unchanged mean-effect inference, and
|
|
61
|
+
the Riley interval's greater width relative to the default rule.
|
|
62
|
+
|
|
63
|
+
## Consequences
|
|
64
|
+
|
|
65
|
+
- existing fits retain their numerical default;
|
|
66
|
+
- the alternative is explicit, auditable, and reproducible;
|
|
67
|
+
- Riley is documented as an alternative approximation rather than an
|
|
68
|
+
automatic small-sample correction;
|
|
69
|
+
- future prediction-interval rules require a separate statistical decision
|
|
70
|
+
and independent reference coverage.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ADR 0004: Hartung-Knapp prediction intervals
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-24
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
ADR 0002 applied the classic pooled-mean variance to every `k - 2`
|
|
9
|
+
random-effects prediction interval. That kept the interval independent of
|
|
10
|
+
`ci_method`, but it diverged from `metafor` Riley predictions and the
|
|
11
|
+
Hartung-Knapp Partlett-Riley option in R `meta`. Both use the covariance
|
|
12
|
+
selected for mean inference inside the prediction variance.
|
|
13
|
+
|
|
14
|
+
This difference was material when the unmodified Hartung-Knapp variance was
|
|
15
|
+
below or above the classic variance. The result metadata still identified the
|
|
16
|
+
interval as `HTS`, so callers could not discover the difference from method
|
|
17
|
+
configuration alone.
|
|
18
|
+
|
|
19
|
+
## Decision
|
|
20
|
+
|
|
21
|
+
Random-effects inverse-variance prediction intervals retain the `k - 2`
|
|
22
|
+
critical value and three-study minimum:
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
mu_hat +/- t_(k - 2, 1 - alpha/2)
|
|
26
|
+
* sqrt(tau^2 + Var_selected(mu_hat))
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- normal inference uses the classic pooled-mean variance and records `HTS`;
|
|
30
|
+
- `hartung_knapp` uses its unmodified adjusted variance and records `HK-PR`;
|
|
31
|
+
- `hartung_knapp_adhoc` uses its lower-bounded adjusted variance and records
|
|
32
|
+
`HK-PR`.
|
|
33
|
+
|
|
34
|
+
Committed values are generated directly from
|
|
35
|
+
`metafor::predict(fit, predtype="Riley")` for all three inference choices.
|
|
36
|
+
Prediction intervals remain unavailable below three included studies and
|
|
37
|
+
retain the explicit warning with three or four studies.
|
|
38
|
+
|
|
39
|
+
## Consequences
|
|
40
|
+
|
|
41
|
+
- prediction intervals and mean intervals use a coherent selected covariance;
|
|
42
|
+
- HK and safeguarded HK prediction intervals can differ from the normal HTS
|
|
43
|
+
interval even when tau-squared and the pooled estimate are unchanged;
|
|
44
|
+
- `result.method.prediction_interval_method` distinguishes `HTS` from
|
|
45
|
+
`HK-PR`;
|
|
46
|
+
- this decision supersedes only the prediction-variance paragraph of ADR 0002.
|
|
@@ -54,7 +54,10 @@ zero.
|
|
|
54
54
|
`row_id` is the zero-based input position. It is independent of the study
|
|
55
55
|
label and remains stable through exclusion, subgroup, leave-one-out, and
|
|
56
56
|
cumulative workflows. Use it when study labels are duplicated or not suitable
|
|
57
|
-
as identifiers.
|
|
57
|
+
as identifiers. Duplicate labels are accepted because several rows can
|
|
58
|
+
legitimately originate from the same publication, but the result records the
|
|
59
|
+
affected row positions in `warnings` so accidental duplication remains
|
|
60
|
+
auditable.
|
|
58
61
|
|
|
59
62
|
The complete row table is available from:
|
|
60
63
|
|
|
@@ -84,6 +87,13 @@ result = ma.meta_analysis(
|
|
|
84
87
|
result.excluded_studies[["row_id", "study", "exclusion_reason"]]
|
|
85
88
|
```
|
|
86
89
|
|
|
90
|
+
For Meta-regression, missingness is resolved across the outcome, uncertainty,
|
|
91
|
+
study label, and every moderator before moderator values are validated.
|
|
92
|
+
Consequently, a moderator value in an already excluded row is retained for
|
|
93
|
+
audit but cannot abort or influence the fitted design matrix. Moderator values
|
|
94
|
+
in included rows must still satisfy the declared numeric or categorical
|
|
95
|
+
contract.
|
|
96
|
+
|
|
87
97
|
Dropped rows do not contribute to pooled estimates, Q, tau-squared, prediction
|
|
88
98
|
intervals, or weights. Missing subgroup labels are always rejected because
|
|
89
99
|
silently assigning or dropping them would change the subgroup definition.
|
|
@@ -92,7 +102,7 @@ silently assigning or dropping them would change the subgroup definition.
|
|
|
92
102
|
|
|
93
103
|
| Input family | Required validation |
|
|
94
104
|
| --- | --- |
|
|
95
|
-
| Generic | finite effect; finite, strictly positive sampling variance |
|
|
105
|
+
| Generic | finite effect; finite, strictly positive sampling variance large enough for a finite float64 inverse weight |
|
|
96
106
|
| Binary | integer event counts and totals; positive totals; `0 <= events <= total` |
|
|
97
107
|
| Continuous | finite means/SDs; non-negative SDs; integer group sizes of at least 2 |
|
|
98
108
|
|
|
@@ -100,6 +110,12 @@ Binary and continuous APIs preserve their raw input columns in
|
|
|
100
110
|
`study_results`. Derived effects, variances, correction indicators, and
|
|
101
111
|
weights appear alongside them.
|
|
102
112
|
|
|
113
|
+
All numerical calculations use float64. Internally derived effects and
|
|
114
|
+
variances must remain finite, and every included sampling variance must be
|
|
115
|
+
large enough to produce a finite inverse-variance weight. Values outside that
|
|
116
|
+
representable range raise `InvalidStudyDataError` instead of returning
|
|
117
|
+
non-finite fitted results.
|
|
118
|
+
|
|
103
119
|
## Exclusion is visible
|
|
104
120
|
|
|
105
121
|
Rows excluded by a configured rule remain present with:
|