PyMetaAnalysis 0.1.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

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.
meta_analyze/_version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Single source of truth for the package version."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.1"
meta_analyze/api.py CHANGED
@@ -13,7 +13,11 @@ from .data import ColumnOrArray, MissingPolicy, normalize_studies
13
13
  from .estimators import fit_inverse_variance
14
14
  from .exceptions import InvalidStudyDataError, UnsupportedMethodError
15
15
  from .heterogeneity import classical_heterogeneity, tau2_inconsistency
16
- from .provenance import add_input_field, build_analysis_provenance
16
+ from .provenance import (
17
+ TransformationRecord,
18
+ add_input_field,
19
+ build_analysis_provenance,
20
+ )
17
21
  from .results import (
18
22
  FitDiagnostics,
19
23
  HeterogeneityResult,
@@ -65,7 +69,8 @@ def _fit_meta_analysis_single(
65
69
  data: pd.DataFrame | None = None,
66
70
  *,
67
71
  effect: ColumnOrArray,
68
- variance: ColumnOrArray,
72
+ variance: ColumnOrArray | None = None,
73
+ standard_error: ColumnOrArray | None = None,
69
74
  study: ColumnOrArray | None = None,
70
75
  model: str = "random",
71
76
  tau2_method: str = "REML",
@@ -82,9 +87,14 @@ def _fit_meta_analysis_single(
82
87
  data:
83
88
  Optional pandas DataFrame. String-valued input arguments select columns
84
89
  from this frame.
85
- effect, variance:
90
+ effect:
86
91
  A DataFrame column name or one-dimensional array-like containing study
87
- effects and strictly positive sampling variances.
92
+ effects.
93
+ variance, standard_error:
94
+ Exactly one must be provided as a DataFrame column name or
95
+ one-dimensional array-like. Values must be finite and strictly
96
+ positive. Standard errors are squared internally to obtain sampling
97
+ variances.
88
98
  study:
89
99
  Optional study label column/array. DataFrame input defaults to its index;
90
100
  array-only input defaults to integer row labels.
@@ -118,6 +128,7 @@ def _fit_meta_analysis_single(
118
128
  data=data,
119
129
  effect=effect,
120
130
  variance=variance,
131
+ standard_error=standard_error,
121
132
  study=study,
122
133
  missing=missing,
123
134
  )
@@ -190,12 +201,30 @@ def _fit_meta_analysis_single(
190
201
  max_iter=max_iter,
191
202
  options=(),
192
203
  )
204
+ transformations: tuple[TransformationRecord, ...] = ()
205
+ if standard_error is not None:
206
+ uncertainty_input = ("standard_error", standard_error)
207
+ transformed_rows = tuple(
208
+ int(row) for row in np.flatnonzero(~pd.isna(studies.variance))
209
+ )
210
+ transformations = (
211
+ TransformationRecord(
212
+ name="standard_error_to_variance",
213
+ affected_rows=transformed_rows,
214
+ ),
215
+ )
216
+ else:
217
+ if variance is None: # pragma: no cover - validated by normalize_studies
218
+ raise RuntimeError("variance input unexpectedly missing")
219
+ uncertainty_input = ("variance", variance)
220
+
193
221
  provenance = build_analysis_provenance(
194
222
  analysis_type="generic",
195
223
  data=data,
196
- inputs=(("effect", effect), ("variance", variance)),
224
+ inputs=(("effect", effect), uncertainty_input),
197
225
  study=study,
198
226
  included=studies.included,
227
+ transformations=transformations,
199
228
  )
200
229
 
201
230
  return MetaAnalysisResult(
@@ -226,6 +255,26 @@ def meta_analysis(
226
255
  *,
227
256
  effect: ColumnOrArray,
228
257
  variance: ColumnOrArray,
258
+ standard_error: None = None,
259
+ study: ColumnOrArray | None = None,
260
+ subgroup: None = None,
261
+ model: str = "random",
262
+ tau2_method: str = "REML",
263
+ ci_method: str = "normal",
264
+ confidence_level: float = 0.95,
265
+ missing: MissingPolicy = "raise",
266
+ atol: float = 1e-10,
267
+ max_iter: int = 1000,
268
+ ) -> MetaAnalysisResult: ...
269
+
270
+
271
+ @overload
272
+ def meta_analysis(
273
+ data: pd.DataFrame | None = None,
274
+ *,
275
+ effect: ColumnOrArray,
276
+ variance: None = None,
277
+ standard_error: ColumnOrArray,
229
278
  study: ColumnOrArray | None = None,
230
279
  subgroup: None = None,
231
280
  model: str = "random",
@@ -244,6 +293,7 @@ def meta_analysis(
244
293
  *,
245
294
  effect: ColumnOrArray,
246
295
  variance: ColumnOrArray,
296
+ standard_error: None = None,
247
297
  study: ColumnOrArray | None = None,
248
298
  subgroup: ColumnOrArray,
249
299
  model: str = "random",
@@ -256,11 +306,31 @@ def meta_analysis(
256
306
  ) -> SubgroupMetaAnalysisResult: ...
257
307
 
258
308
 
309
+ @overload
259
310
  def meta_analysis(
260
311
  data: pd.DataFrame | None = None,
261
312
  *,
262
313
  effect: ColumnOrArray,
263
- variance: ColumnOrArray,
314
+ variance: None = None,
315
+ standard_error: ColumnOrArray,
316
+ study: ColumnOrArray | None = None,
317
+ subgroup: ColumnOrArray,
318
+ model: str = "random",
319
+ tau2_method: str = "REML",
320
+ ci_method: str = "normal",
321
+ confidence_level: float = 0.95,
322
+ missing: MissingPolicy = "raise",
323
+ atol: float = 1e-10,
324
+ max_iter: int = 1000,
325
+ ) -> SubgroupMetaAnalysisResult: ...
326
+
327
+
328
+ def meta_analysis(
329
+ data: pd.DataFrame | None = None,
330
+ *,
331
+ effect: ColumnOrArray,
332
+ variance: ColumnOrArray | None = None,
333
+ standard_error: ColumnOrArray | None = None,
264
334
  study: ColumnOrArray | None = None,
265
335
  subgroup: ColumnOrArray | None = None,
266
336
  model: str = "random",
@@ -273,18 +343,21 @@ def meta_analysis(
273
343
  ) -> MetaAnalysisResult | SubgroupMetaAnalysisResult:
274
344
  """Fit a generic inverse-variance meta-analysis, optionally by subgroup.
275
345
 
276
- ``effect`` and ``variance`` accept DataFrame column names or one-dimensional
277
- array-like values. Sampling variances must be finite and strictly positive.
278
- The default is a REML random-effects model with a normal confidence
279
- interval. ``subgroup`` returns :class:`SubgroupMetaAnalysisResult` when
280
- supplied; otherwise the return value is :class:`MetaAnalysisResult`.
281
- Missing subgroup labels are rejected explicitly.
346
+ ``effect`` and the selected uncertainty input accept DataFrame column names
347
+ or one-dimensional array-like values. Supply exactly one of ``variance`` or
348
+ ``standard_error``; standard errors are squared internally. Uncertainty
349
+ values must be finite and strictly positive. The default is a REML
350
+ random-effects model with a normal confidence interval. ``subgroup``
351
+ returns :class:`SubgroupMetaAnalysisResult` when supplied; otherwise the
352
+ return value is :class:`MetaAnalysisResult`. Missing subgroup labels are
353
+ rejected explicitly.
282
354
  """
283
355
 
284
356
  overall = _fit_meta_analysis_single(
285
357
  data,
286
358
  effect=effect,
287
359
  variance=variance,
360
+ standard_error=standard_error,
288
361
  study=study,
289
362
  model=model,
290
363
  tau2_method=tau2_method,
meta_analyze/data.py CHANGED
@@ -70,6 +70,7 @@ def _study_labels(
70
70
  *,
71
71
  data: pd.DataFrame | None,
72
72
  length: int,
73
+ uncertainty_label: str = "variance",
73
74
  ) -> NDArray[np.object_]:
74
75
  if study is None:
75
76
  labels: NDArray[Any]
@@ -82,17 +83,33 @@ def _study_labels(
82
83
 
83
84
  if len(labels) != length:
84
85
  raise InvalidStudyDataError(
85
- f"study has length {len(labels)}, but effect and variance have "
86
- f"length {length}."
86
+ f"study has length {len(labels)}, but effect and {uncertainty_label} "
87
+ f"have length {length}."
87
88
  )
88
89
  return np.asarray(labels, dtype=object)
89
90
 
90
91
 
92
+ def _select_uncertainty_input(
93
+ variance: ColumnOrArray | None,
94
+ standard_error: ColumnOrArray | None,
95
+ ) -> tuple[ColumnOrArray, str, str]:
96
+ if (variance is None) == (standard_error is None):
97
+ raise InvalidStudyDataError(
98
+ "Exactly one of variance or standard_error must be provided."
99
+ )
100
+ if standard_error is not None:
101
+ return standard_error, "standard_error", "standard error"
102
+ if variance is None: # pragma: no cover - guarded by the exclusive check
103
+ raise RuntimeError("variance input unexpectedly missing")
104
+ return variance, "variance", "variance"
105
+
106
+
91
107
  def normalize_studies(
92
108
  *,
93
109
  data: pd.DataFrame | None,
94
110
  effect: ColumnOrArray,
95
- variance: ColumnOrArray,
111
+ variance: ColumnOrArray | None,
112
+ standard_error: ColumnOrArray | None = None,
96
113
  study: ColumnOrArray | None,
97
114
  missing: MissingPolicy,
98
115
  ) -> NormalizedStudies:
@@ -103,12 +120,15 @@ def normalize_studies(
103
120
  if missing not in {"raise", "drop"}:
104
121
  raise InvalidStudyDataError("missing must be either 'raise' or 'drop'.")
105
122
 
123
+ uncertainty, uncertainty_name, uncertainty_label = _select_uncertainty_input(
124
+ variance, standard_error
125
+ )
106
126
  raw_effect = _resolve_vector(effect, data=data, name="effect")
107
- raw_variance = _resolve_vector(variance, data=data, name="variance")
108
- if len(raw_effect) != len(raw_variance):
127
+ raw_uncertainty = _resolve_vector(uncertainty, data=data, name=uncertainty_name)
128
+ if len(raw_effect) != len(raw_uncertainty):
109
129
  raise InvalidStudyDataError(
110
- "effect and variance must have the same length; "
111
- f"got {len(raw_effect)} and {len(raw_variance)}."
130
+ f"effect and {uncertainty_label} must have the same length; "
131
+ f"got {len(raw_effect)} and {len(raw_uncertainty)}."
112
132
  )
113
133
  if data is not None and len(data) != len(raw_effect):
114
134
  raise InvalidStudyDataError(
@@ -116,55 +136,77 @@ def normalize_studies(
116
136
  "DataFrame row."
117
137
  )
118
138
 
119
- labels = _study_labels(study, data=data, length=len(raw_effect))
139
+ labels = _study_labels(
140
+ study,
141
+ data=data,
142
+ length=len(raw_effect),
143
+ uncertainty_label=uncertainty_label,
144
+ )
120
145
 
121
146
  try:
122
147
  effect_values = np.asarray(raw_effect, dtype=np.float64)
123
- variance_values = np.asarray(raw_variance, dtype=np.float64)
148
+ uncertainty_values = np.asarray(raw_uncertainty, dtype=np.float64)
124
149
  except (TypeError, ValueError) as error:
125
150
  raise InvalidStudyDataError(
126
- "effect and variance must contain numeric values."
151
+ f"effect and {uncertainty_label} must contain numeric values."
127
152
  ) from error
128
153
 
129
154
  effect_missing = pd.isna(effect_values)
130
- variance_missing = pd.isna(variance_values)
131
- any_missing = effect_missing | variance_missing
155
+ uncertainty_missing = pd.isna(uncertainty_values)
156
+ any_missing = effect_missing | uncertainty_missing
132
157
  if np.any(any_missing) and missing == "raise":
133
158
  rows = np.flatnonzero(any_missing).tolist()
134
159
  raise InvalidStudyDataError(
135
- f"Missing effect or variance values at row positions {rows}; "
160
+ f"Missing effect or {uncertainty_label} values at row positions {rows}; "
136
161
  "use missing='drop' to exclude them explicitly."
137
162
  )
138
163
 
139
164
  finite_effect = np.isfinite(effect_values) | effect_missing
140
- finite_variance = np.isfinite(variance_values) | variance_missing
165
+ finite_uncertainty = np.isfinite(uncertainty_values) | uncertainty_missing
141
166
  if not np.all(finite_effect):
142
167
  rows = np.flatnonzero(~finite_effect).tolist()
143
168
  raise InvalidStudyDataError(
144
169
  f"Effect values must be finite; invalid rows: {rows}."
145
170
  )
146
- if not np.all(finite_variance):
147
- rows = np.flatnonzero(~finite_variance).tolist()
171
+ if not np.all(finite_uncertainty):
172
+ rows = np.flatnonzero(~finite_uncertainty).tolist()
148
173
  raise InvalidStudyDataError(
149
- f"Variance values must be finite; invalid rows: {rows}."
174
+ f"{uncertainty_label.capitalize()} values must be finite; "
175
+ f"invalid rows: {rows}."
150
176
  )
151
177
 
152
- nonpositive_variance = (~variance_missing) & (variance_values <= 0.0)
153
- if np.any(nonpositive_variance):
154
- rows = np.flatnonzero(nonpositive_variance).tolist()
178
+ nonpositive_uncertainty = (~uncertainty_missing) & (uncertainty_values <= 0.0)
179
+ if np.any(nonpositive_uncertainty):
180
+ rows = np.flatnonzero(nonpositive_uncertainty).tolist()
155
181
  raise InvalidStudyDataError(
156
- f"Sampling variances must be strictly positive; invalid rows: {rows}."
182
+ f"Sampling {uncertainty_label}s must be strictly positive; "
183
+ f"invalid rows: {rows}."
157
184
  )
158
185
 
186
+ if uncertainty_name == "standard_error":
187
+ with np.errstate(over="ignore", under="ignore", invalid="ignore"):
188
+ variance_values = np.square(uncertainty_values)
189
+ invalid_variance = (~uncertainty_missing) & (
190
+ (~np.isfinite(variance_values)) | (variance_values <= 0.0)
191
+ )
192
+ if np.any(invalid_variance):
193
+ rows = np.flatnonzero(invalid_variance).tolist()
194
+ raise InvalidStudyDataError(
195
+ "Standard errors must produce finite, strictly positive sampling "
196
+ f"variances after squaring; invalid rows: {rows}."
197
+ )
198
+ else:
199
+ variance_values = uncertainty_values
200
+
159
201
  included = ~any_missing
160
202
  reasons = np.full(len(effect_values), None, dtype=object)
161
203
  for index in np.flatnonzero(any_missing):
162
- if effect_missing[index] and variance_missing[index]:
163
- reasons[index] = "missing effect and variance"
204
+ if effect_missing[index] and uncertainty_missing[index]:
205
+ reasons[index] = f"missing effect and {uncertainty_label}"
164
206
  elif effect_missing[index]:
165
207
  reasons[index] = "missing effect"
166
208
  else:
167
- reasons[index] = "missing variance"
209
+ reasons[index] = f"missing {uncertainty_label}"
168
210
 
169
211
  if not np.any(included):
170
212
  raise InvalidStudyDataError(
meta_analyze/reporting.py CHANGED
@@ -105,6 +105,13 @@ def method_details(result: MetaAnalysisResult) -> str:
105
105
  f"using {_measure_description(result.measure)}, pooled with {pooling}."
106
106
  ]
107
107
 
108
+ standard_error_rows = _transformation_rows(result, "standard_error_to_variance")
109
+ if standard_error_rows:
110
+ sentences.append(
111
+ "Supplied standard errors were squared to obtain sampling "
112
+ f"variances for {len(standard_error_rows)} row(s)."
113
+ )
114
+
108
115
  if result.model == "random":
109
116
  sentences.append(
110
117
  "Between-study variance was estimated with "
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyMetaAnalysis
3
- Version: 0.1.0
3
+ Version: 0.2.1
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
7
7
  Project-URL: Issues, https://github.com/ZhaoboDing/PyMetaAnalysis/issues
8
8
  Project-URL: Changelog, https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/CHANGELOG.md
9
- Author: PyMetaAnalysis contributors
9
+ Author-email: Zhaobo Ding <ding.zb@yahoo.com>
10
10
  Maintainer-email: Zhaobo Ding <ding.zb@yahoo.com>
11
11
  License-Expression: MIT
12
12
  License-File: LICENSE
@@ -51,7 +51,7 @@ Description-Content-Type: text/markdown
51
51
 
52
52
  [![CI](https://github.com/ZhaoboDing/PyMetaAnalysis/actions/workflows/ci.yml/badge.svg)](https://github.com/ZhaoboDing/PyMetaAnalysis/actions/workflows/ci.yml)
53
53
  [![Documentation](https://github.com/ZhaoboDing/PyMetaAnalysis/actions/workflows/pages.yml/badge.svg)](https://zhaoboding.github.io/PyMetaAnalysis/)
54
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
54
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/LICENSE)
55
55
 
56
56
  PyMetaAnalysis is an early-stage, pandas-first Python library for conventional
57
57
  study-level meta-analysis. It accepts DataFrames, NumPy arrays, and ordinary
@@ -115,7 +115,7 @@ subgroup differences.
115
115
 
116
116
  | Input | Effects | Pooling/models |
117
117
  | --- | --- | --- |
118
- | Effect + sampling variance | Generic | Common/random inverse variance |
118
+ | Effect + sampling variance or standard error | Generic | Common/random inverse variance |
119
119
  | Two-group events + totals | OR, RR, RD | Common MH OR/RR; common/random IV |
120
120
  | Two-group means + SDs + sizes | MD, Hedges' g | Common/random inverse variance |
121
121
 
@@ -124,6 +124,10 @@ and DerSimonian-Laird tau-squared estimators. Mean confidence intervals support
124
124
  the normal default plus unmodified and safeguarded Hartung-Knapp variants.
125
125
  Eligible random-effects fits include an HTS prediction interval.
126
126
 
127
+ Generic analyses accept exactly one of `variance=` or `standard_error=`.
128
+ Standard errors are squared internally and the conversion is recorded in the
129
+ result provenance.
130
+
127
131
  Sparse binary behavior is explicit: study-level and Mantel-Haenszel continuity
128
132
  corrections are separate, relative-effect double-zero/double-all rows remain
129
133
  visible as exclusions, and RD exposes
@@ -174,18 +178,18 @@ are descriptive small-study-effect diagnostics, not proof of publication bias.
174
178
  The complete documentation is published at
175
179
  [zhaoboding.github.io/PyMetaAnalysis](https://zhaoboding.github.io/PyMetaAnalysis/).
176
180
 
177
- - [Installation](docs/installation.md)
178
- - [Getting started](docs/getting-started.md)
179
- - [Input data and row decisions](docs/guides/input-data.md)
180
- - [Generic](docs/guides/generic-effects.md), [binary](docs/guides/binary-outcomes.md), and [continuous](docs/guides/continuous-outcomes.md) guides
181
- - [Choosing methods](docs/guides/method-selection.md) and [statistical formulas](docs/methods/statistical-methods.md)
182
- - [Sensitivity analysis](docs/guides/sensitivity-analysis.md) and [plotting](docs/guides/plotting.md)
183
- - [Public API](docs/reference/api.md), [result objects](docs/reference/results.md), and [report schema](docs/reference/report-schema.md)
184
- - [Validation strategy](docs/validation.md) and [scope/limitations](docs/limitations.md)
185
- - [Citation guidance](docs/citation.md)
186
- - [R `meta`/`metafor` mapping](docs/guides/r-interoperability.md)
187
-
188
- An executable [end-to-end notebook](examples/quickstart.ipynb) uses synthetic
181
+ - [Installation](https://zhaoboding.github.io/PyMetaAnalysis/installation/)
182
+ - [Getting started](https://zhaoboding.github.io/PyMetaAnalysis/getting-started/)
183
+ - [Input data and row decisions](https://zhaoboding.github.io/PyMetaAnalysis/guides/input-data/)
184
+ - [Generic](https://zhaoboding.github.io/PyMetaAnalysis/guides/generic-effects/), [binary](https://zhaoboding.github.io/PyMetaAnalysis/guides/binary-outcomes/), and [continuous](https://zhaoboding.github.io/PyMetaAnalysis/guides/continuous-outcomes/) guides
185
+ - [Choosing methods](https://zhaoboding.github.io/PyMetaAnalysis/guides/method-selection/) and [statistical formulas](https://zhaoboding.github.io/PyMetaAnalysis/methods/statistical-methods/)
186
+ - [Sensitivity analysis](https://zhaoboding.github.io/PyMetaAnalysis/guides/sensitivity-analysis/) and [plotting](https://zhaoboding.github.io/PyMetaAnalysis/guides/plotting/)
187
+ - [Public API](https://zhaoboding.github.io/PyMetaAnalysis/reference/api/), [result objects](https://zhaoboding.github.io/PyMetaAnalysis/reference/results/), and [report schema](https://zhaoboding.github.io/PyMetaAnalysis/reference/report-schema/)
188
+ - [Validation strategy](https://zhaoboding.github.io/PyMetaAnalysis/validation/) and [scope/limitations](https://zhaoboding.github.io/PyMetaAnalysis/limitations/)
189
+ - [Citation guidance](https://zhaoboding.github.io/PyMetaAnalysis/citation/)
190
+ - [R `meta`/`metafor` mapping](https://zhaoboding.github.io/PyMetaAnalysis/guides/r-interoperability/)
191
+
192
+ An executable [end-to-end notebook](https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/examples/quickstart.ipynb) uses synthetic
189
193
  data to demonstrate analysis, provenance, reporting, sensitivity, and plotting.
190
194
 
191
195
  Build the complete site locally with:
@@ -203,16 +207,22 @@ edge cases, and committed R `metafor` reference fixtures. CI covers Python
203
207
  distribution builds.
204
208
 
205
209
  This is independent cross-software validation, not a formal external
206
- statistical audit. See [validation](docs/validation.md) for exact coverage.
210
+ statistical audit. See
211
+ [validation](https://zhaoboding.github.io/PyMetaAnalysis/validation/) for exact
212
+ coverage.
207
213
 
208
214
  ## Contributing
209
215
 
210
- See [CONTRIBUTING.md](CONTRIBUTING.md) and the full
211
- [development guide](docs/development.md). Statistical changes require formula
216
+ See
217
+ [CONTRIBUTING.md](https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/CONTRIBUTING.md)
218
+ and the full
219
+ [development guide](https://zhaoboding.github.io/PyMetaAnalysis/development/).
220
+ Statistical changes require formula
212
221
  documentation, boundary tests, and an independent comparison where available.
213
222
 
214
- Security-sensitive reports should follow [SECURITY.md](SECURITY.md).
223
+ Security-sensitive reports should follow
224
+ [SECURITY.md](https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/SECURITY.md).
215
225
 
216
226
  ## License
217
227
 
218
- [MIT](LICENSE)
228
+ [MIT](https://github.com/ZhaoboDing/PyMetaAnalysis/blob/main/LICENSE)
@@ -1,15 +1,15 @@
1
1
  meta_analyze/__init__.py,sha256=POInICUoVRrqR7s9sgJReHsbxBYNNlqagJDduHWC-3I,1602
2
- meta_analyze/_version.py,sha256=-UYTpK8lRuzcw9BEWkdBHyJiS_vjvg0P06Wo2xs--us,77
3
- meta_analyze/api.py,sha256=C3Hc9nmoFtYzC5ar5Lh2b-I3fisghquWs7ue6q1alu4,10763
2
+ meta_analyze/_version.py,sha256=bV7jlwuImq2OrGXG_x4vGXNic3lNrNcFEgpc6aKy37M,77
3
+ meta_analyze/api.py,sha256=pMMMzsKkiBc_3vvNxeqjZG3Rs3RJpyVDqr7BflhQaak,13080
4
4
  meta_analyze/binary_api.py,sha256=kH_1zuAshRCJ_MjbbPt30CmMAPr49N2hASZmODnMaqM,18664
5
5
  meta_analyze/config.py,sha256=IL8VX0xDRv18giwbk2m-P_XjBjOo_GsN_B-H4-C7s8E,831
6
6
  meta_analyze/continuous_api.py,sha256=jAsVB9TqTDKGLw5MWCNGXxiBx5u9QVSeAR0fuN9WRYE,11457
7
- meta_analyze/data.py,sha256=KVfjYJc-oHuFaaHqLN4aRHz5eoA7MOn9P6KxuoY-9oQ,6085
7
+ meta_analyze/data.py,sha256=QCYNzEmjOgjVyFDIJrf4M4dTP-ZctPOOlUesx23KObw,7869
8
8
  meta_analyze/exceptions.py,sha256=h4PPm8mcxSyUQax0YrqgIhy7GCF7wj2uVL4BWmwWImA,666
9
9
  meta_analyze/heterogeneity.py,sha256=xQ2e5012AZG1YKuq2EDl4ccYgguC2Se5LJOT1WMHrVo,3308
10
10
  meta_analyze/provenance.py,sha256=PrRubpJRn2muvJNun2juMKs-VV4QVT4T81BxvHNuKck,5858
11
11
  meta_analyze/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
12
- meta_analyze/reporting.py,sha256=cwf2UR-pUgm9KDszms2d9oiHuZKc2N_N0QEkqt5Z9-4,15958
12
+ meta_analyze/reporting.py,sha256=tgkVVolIyWhXVdGBwm3bV32nPHJ8fppjRpOx0ucOv44,16244
13
13
  meta_analyze/results.py,sha256=Jq9O0uwnmseQjYBNBSqtlXhh9U_D-th5b6nQHj3AsbQ,17048
14
14
  meta_analyze/sensitivity.py,sha256=3p1Mu5AdeugYcLZtTV_2YEgfgmBJ_y1Bnbcgj33m5Mw,18584
15
15
  meta_analyze/subgroups.py,sha256=CSevfbLfA79Z55RyLGKyjUSDl7TGladdHbrJXhKSzCY,5985
@@ -25,7 +25,7 @@ meta_analyze/plotting/_utils.py,sha256=3vg-0Wtjlf7LKpXkw2sNnkLNMAS83K_SwxXaneT74
25
25
  meta_analyze/plotting/forest.py,sha256=NkqcJC7HLfDzl-fW2rNEeH2sozCVpZwsjFuPWFYVNKs,6088
26
26
  meta_analyze/plotting/funnel.py,sha256=Mdy1O5uVw4OZF8PvXiDyG7AMANz7vkef9ru-D61_k1Q,5577
27
27
  meta_analyze/plotting/subgroup_forest.py,sha256=hEIDtmme2javG6YgsHobAS5EK0lEoe07N0NweU9JDdg,8341
28
- pymetaanalysis-0.1.0.dist-info/METADATA,sha256=yN4WCkkJUsDBQnqL4BtPLrtRTT1KFJRvtiCmlcZ_KIw,7864
29
- pymetaanalysis-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
30
- pymetaanalysis-0.1.0.dist-info/licenses/LICENSE,sha256=CBE_u7LfEteKb_1My8s9obP0YkjJVzcWlgHSDiqa9ts,1084
31
- pymetaanalysis-0.1.0.dist-info/RECORD,,
28
+ pymetaanalysis-0.2.1.dist-info/METADATA,sha256=BalGMtJG7h_7DplNp1lWzw35Y8go2b_EkasFPstVTMY,9040
29
+ pymetaanalysis-0.2.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
30
+ pymetaanalysis-0.2.1.dist-info/licenses/LICENSE,sha256=CBE_u7LfEteKb_1My8s9obP0YkjJVzcWlgHSDiqa9ts,1084
31
+ pymetaanalysis-0.2.1.dist-info/RECORD,,