pymmeans 0.1.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.
Files changed (186) hide show
  1. pymmeans-0.1.0/.gitignore +62 -0
  2. pymmeans-0.1.0/CHANGELOG.md +53 -0
  3. pymmeans-0.1.0/CITATION.cff +62 -0
  4. pymmeans-0.1.0/LICENSE +681 -0
  5. pymmeans-0.1.0/PKG-INFO +294 -0
  6. pymmeans-0.1.0/README.md +244 -0
  7. pymmeans-0.1.0/benchmarks/bench_performance.py +597 -0
  8. pymmeans-0.1.0/benchmarks/r_benchmark.R +85 -0
  9. pymmeans-0.1.0/benchmarks/run_comparison.py +183 -0
  10. pymmeans-0.1.0/docs/PERFORMANCE_REPORT.md +21 -0
  11. pymmeans-0.1.0/docs/api/adapters.md +8 -0
  12. pymmeans-0.1.0/docs/api/adjustments.md +3 -0
  13. pymmeans-0.1.0/docs/api/cld.md +3 -0
  14. pymmeans-0.1.0/docs/api/contrasts.md +3 -0
  15. pymmeans-0.1.0/docs/api/diagnostics.md +3 -0
  16. pymmeans-0.1.0/docs/api/emmeans.md +3 -0
  17. pymmeans-0.1.0/docs/api/emtrends.md +3 -0
  18. pymmeans-0.1.0/docs/api/joint.md +3 -0
  19. pymmeans-0.1.0/docs/api/ml.md +3 -0
  20. pymmeans-0.1.0/docs/api/multinom.md +3 -0
  21. pymmeans-0.1.0/docs/api/options.md +3 -0
  22. pymmeans-0.1.0/docs/api/ordinal.md +3 -0
  23. pymmeans-0.1.0/docs/api/pbktest.md +3 -0
  24. pymmeans-0.1.0/docs/api/pbmodcomp.md +3 -0
  25. pymmeans-0.1.0/docs/api/plotting.md +3 -0
  26. pymmeans-0.1.0/docs/api/posterior.md +3 -0
  27. pymmeans-0.1.0/docs/api/pwpm.md +3 -0
  28. pymmeans-0.1.0/docs/api/qdrg.md +3 -0
  29. pymmeans-0.1.0/docs/api/ref_grid.md +3 -0
  30. pymmeans-0.1.0/docs/api/satterthwaite.md +3 -0
  31. pymmeans-0.1.0/docs/api/summary.md +3 -0
  32. pymmeans-0.1.0/docs/api/summary_layer.md +10 -0
  33. pymmeans-0.1.0/docs/api/survey.md +3 -0
  34. pymmeans-0.1.0/docs/api/transforms.md +3 -0
  35. pymmeans-0.1.0/docs/api/utils.md +3 -0
  36. pymmeans-0.1.0/docs/example_interaction_plot.png +0 -0
  37. pymmeans-0.1.0/docs/getting-started.md +149 -0
  38. pymmeans-0.1.0/docs/index.md +42 -0
  39. pymmeans-0.1.0/docs/r_parity_matrix.md +256 -0
  40. pymmeans-0.1.0/docs/v0_2_roadmap.md +118 -0
  41. pymmeans-0.1.0/docs/vs-r.md +122 -0
  42. pymmeans-0.1.0/examples/basic_ols.py +52 -0
  43. pymmeans-0.1.0/examples/glm_logistic.py +63 -0
  44. pymmeans-0.1.0/examples/make_plot_artifact.py +56 -0
  45. pymmeans-0.1.0/examples/pymmeans_showcase.html +9162 -0
  46. pymmeans-0.1.0/examples/pymmeans_showcase.ipynb +1533 -0
  47. pymmeans-0.1.0/mkdocs.yml +94 -0
  48. pymmeans-0.1.0/pyproject.toml +136 -0
  49. pymmeans-0.1.0/src/pymmeans/__init__.py +195 -0
  50. pymmeans-0.1.0/src/pymmeans/adapters.py +212 -0
  51. pymmeans-0.1.0/src/pymmeans/adjustments.py +668 -0
  52. pymmeans-0.1.0/src/pymmeans/analytic.py +379 -0
  53. pymmeans-0.1.0/src/pymmeans/cld.py +387 -0
  54. pymmeans-0.1.0/src/pymmeans/contrasts.py +2148 -0
  55. pymmeans-0.1.0/src/pymmeans/diagnostics.py +422 -0
  56. pymmeans-0.1.0/src/pymmeans/emmeans.py +1358 -0
  57. pymmeans-0.1.0/src/pymmeans/estimability.py +144 -0
  58. pymmeans-0.1.0/src/pymmeans/joint.py +672 -0
  59. pymmeans-0.1.0/src/pymmeans/ml.py +657 -0
  60. pymmeans-0.1.0/src/pymmeans/multinom.py +376 -0
  61. pymmeans-0.1.0/src/pymmeans/options.py +131 -0
  62. pymmeans-0.1.0/src/pymmeans/ordinal.py +464 -0
  63. pymmeans-0.1.0/src/pymmeans/pbktest.py +849 -0
  64. pymmeans-0.1.0/src/pymmeans/pbmodcomp.py +663 -0
  65. pymmeans-0.1.0/src/pymmeans/plotting.py +630 -0
  66. pymmeans-0.1.0/src/pymmeans/posterior.py +564 -0
  67. pymmeans-0.1.0/src/pymmeans/pwpm.py +261 -0
  68. pymmeans-0.1.0/src/pymmeans/qdrg.py +270 -0
  69. pymmeans-0.1.0/src/pymmeans/quantile.py +276 -0
  70. pymmeans-0.1.0/src/pymmeans/ref_grid.py +324 -0
  71. pymmeans-0.1.0/src/pymmeans/satterthwaite.py +1144 -0
  72. pymmeans-0.1.0/src/pymmeans/summary.py +1527 -0
  73. pymmeans-0.1.0/src/pymmeans/summary_layer.py +2212 -0
  74. pymmeans-0.1.0/src/pymmeans/survey.py +458 -0
  75. pymmeans-0.1.0/src/pymmeans/transforms.py +1538 -0
  76. pymmeans-0.1.0/src/pymmeans/trends.py +272 -0
  77. pymmeans-0.1.0/src/pymmeans/utils.py +972 -0
  78. pymmeans-0.1.0/tests/conftest.py +11 -0
  79. pymmeans-0.1.0/tests/r_reference/README.md +38 -0
  80. pymmeans-0.1.0/tests/r_reference/afex_data.csv +121 -0
  81. pymmeans-0.1.0/tests/r_reference/afex_emm_A_by_B.csv +7 -0
  82. pymmeans-0.1.0/tests/r_reference/afex_joint_tests.csv +4 -0
  83. pymmeans-0.1.0/tests/r_reference/afex_pairs_A_by_B.csv +4 -0
  84. pymmeans-0.1.0/tests/r_reference/auto_noise_data.csv +37 -0
  85. pymmeans-0.1.0/tests/r_reference/auto_noise_pairs_size_by_type.csv +7 -0
  86. pymmeans-0.1.0/tests/r_reference/bias_adjust_data.csv +121 -0
  87. pymmeans-0.1.0/tests/r_reference/bias_adjust_emm.csv +3 -0
  88. pymmeans-0.1.0/tests/r_reference/cross_validation.R +188 -0
  89. pymmeans-0.1.0/tests/r_reference/exposure_data.csv +21 -0
  90. pymmeans-0.1.0/tests/r_reference/exposure_emm_response.csv +3 -0
  91. pymmeans-0.1.0/tests/r_reference/generate_cv_data.py +230 -0
  92. pymmeans-0.1.0/tests/r_reference/generate_r_reference.R +47 -0
  93. pymmeans-0.1.0/tests/r_reference/kr_emm_df.csv +4 -0
  94. pymmeans-0.1.0/tests/r_reference/kr_reference.R +90 -0
  95. pymmeans-0.1.0/tests/r_reference/kr_reference.csv +4 -0
  96. pymmeans-0.1.0/tests/r_reference/kr_reference_data.csv +161 -0
  97. pymmeans-0.1.0/tests/r_reference/kr_reference_rs.csv +3 -0
  98. pymmeans-0.1.0/tests/r_reference/kr_reference_rs_data.csv +181 -0
  99. pymmeans-0.1.0/tests/r_reference/lme4_ri_data.csv +121 -0
  100. pymmeans-0.1.0/tests/r_reference/lme4_ri_emm_kr.csv +3 -0
  101. pymmeans-0.1.0/tests/r_reference/lme4_ri_emm_satt.csv +3 -0
  102. pymmeans-0.1.0/tests/r_reference/lme4_ri_pairs_satt.csv +2 -0
  103. pymmeans-0.1.0/tests/r_reference/lme4_ri_vcov_kr.csv +4 -0
  104. pymmeans-0.1.0/tests/r_reference/lme4_rs_data.csv +241 -0
  105. pymmeans-0.1.0/tests/r_reference/lme4_rs_emm_satt.csv +3 -0
  106. pymmeans-0.1.0/tests/r_reference/marginal_data.csv +301 -0
  107. pymmeans-0.1.0/tests/r_reference/marginal_emm_a.csv +4 -0
  108. pymmeans-0.1.0/tests/r_reference/marginal_pairs_a.csv +4 -0
  109. pymmeans-0.1.0/tests/r_reference/multinom_data.csv +501 -0
  110. pymmeans-0.1.0/tests/r_reference/multinom_emm_latent.csv +10 -0
  111. pymmeans-0.1.0/tests/r_reference/multinom_emm_prob.csv +10 -0
  112. pymmeans-0.1.0/tests/r_reference/multinom_reference.R +34 -0
  113. pymmeans-0.1.0/tests/r_reference/neuralgia_data.csv +61 -0
  114. pymmeans-0.1.0/tests/r_reference/neuralgia_emm_treatment_response.csv +4 -0
  115. pymmeans-0.1.0/tests/r_reference/oats_data.csv +73 -0
  116. pymmeans-0.1.0/tests/r_reference/oats_emm_nitro.csv +5 -0
  117. pymmeans-0.1.0/tests/r_reference/ordinal_data.csv +501 -0
  118. pymmeans-0.1.0/tests/r_reference/ordinal_emm_cumprob.csv +7 -0
  119. pymmeans-0.1.0/tests/r_reference/ordinal_emm_latent.csv +4 -0
  120. pymmeans-0.1.0/tests/r_reference/ordinal_emm_meanclass.csv +4 -0
  121. pymmeans-0.1.0/tests/r_reference/ordinal_emm_prob.csv +10 -0
  122. pymmeans-0.1.0/tests/r_reference/ordinal_reference.R +63 -0
  123. pymmeans-0.1.0/tests/r_reference/pbkrtest_ftests.R +112 -0
  124. pymmeans-0.1.0/tests/r_reference/pbkrtest_ftests.csv +5 -0
  125. pymmeans-0.1.0/tests/r_reference/pbkrtest_ftests_data.csv +181 -0
  126. pymmeans-0.1.0/tests/r_reference/pbmodcomp_data.csv +181 -0
  127. pymmeans-0.1.0/tests/r_reference/pbmodcomp_lrt_dist.csv +5001 -0
  128. pymmeans-0.1.0/tests/r_reference/pbmodcomp_reference.R +61 -0
  129. pymmeans-0.1.0/tests/r_reference/pbmodcomp_summary.csv +6 -0
  130. pymmeans-0.1.0/tests/r_reference/pigs_data.csv +30 -0
  131. pymmeans-0.1.0/tests/r_reference/pigs_emm_source.csv +4 -0
  132. pymmeans-0.1.0/tests/r_reference/pigs_pairs_source.csv +4 -0
  133. pymmeans-0.1.0/tests/r_reference/splines_data.csv +101 -0
  134. pymmeans-0.1.0/tests/r_reference/splines_emm_bs_g.csv +4 -0
  135. pymmeans-0.1.0/tests/r_reference/splines_emm_bs_gx.csv +10 -0
  136. pymmeans-0.1.0/tests/r_reference/splines_emm_bs_interact.csv +10 -0
  137. pymmeans-0.1.0/tests/r_reference/splines_reference.R +48 -0
  138. pymmeans-0.1.0/tests/r_reference/spray_emm.csv +7 -0
  139. pymmeans-0.1.0/tests/r_reference/spray_pairs.csv +16 -0
  140. pymmeans-0.1.0/tests/r_reference/survey_binomial_coef.csv +4 -0
  141. pymmeans-0.1.0/tests/r_reference/survey_binomial_data.csv +251 -0
  142. pymmeans-0.1.0/tests/r_reference/survey_binomial_emm.csv +3 -0
  143. pymmeans-0.1.0/tests/r_reference/survey_gamma_coef.csv +5 -0
  144. pymmeans-0.1.0/tests/r_reference/survey_gamma_data.csv +251 -0
  145. pymmeans-0.1.0/tests/r_reference/survey_gamma_emm.csv +4 -0
  146. pymmeans-0.1.0/tests/r_reference/survey_poisson_coef.csv +5 -0
  147. pymmeans-0.1.0/tests/r_reference/survey_poisson_data.csv +301 -0
  148. pymmeans-0.1.0/tests/r_reference/survey_poisson_emm.csv +4 -0
  149. pymmeans-0.1.0/tests/r_reference/survey_srs_coef.csv +5 -0
  150. pymmeans-0.1.0/tests/r_reference/survey_srs_data.csv +201 -0
  151. pymmeans-0.1.0/tests/r_reference/survey_srs_emm.csv +4 -0
  152. pymmeans-0.1.0/tests/r_reference/tooth_emm_supp_by_dose.csv +7 -0
  153. pymmeans-0.1.0/tests/r_reference/ucla_mouse.csv +1201 -0
  154. pymmeans-0.1.0/tests/r_reference/warp_emm_tension_by_wool.csv +7 -0
  155. pymmeans-0.1.0/tests/r_reference/warp_pairs_tension_by_wool.csv +7 -0
  156. pymmeans-0.1.0/tests/test_adapters.py +155 -0
  157. pymmeans-0.1.0/tests/test_adjustments.py +167 -0
  158. pymmeans-0.1.0/tests/test_analytic.py +139 -0
  159. pymmeans-0.1.0/tests/test_contrasts.py +304 -0
  160. pymmeans-0.1.0/tests/test_diagnostics.py +163 -0
  161. pymmeans-0.1.0/tests/test_emmeans.py +302 -0
  162. pymmeans-0.1.0/tests/test_estimability.py +77 -0
  163. pymmeans-0.1.0/tests/test_formula_expressions.py +132 -0
  164. pymmeans-0.1.0/tests/test_joint.py +93 -0
  165. pymmeans-0.1.0/tests/test_linearmodels.py +71 -0
  166. pymmeans-0.1.0/tests/test_mixedlm.py +67 -0
  167. pymmeans-0.1.0/tests/test_multinom.py +180 -0
  168. pymmeans-0.1.0/tests/test_ordinal.py +234 -0
  169. pymmeans-0.1.0/tests/test_pbktest.py +412 -0
  170. pymmeans-0.1.0/tests/test_pbmodcomp.py +555 -0
  171. pymmeans-0.1.0/tests/test_plotting.py +110 -0
  172. pymmeans-0.1.0/tests/test_posterior.py +194 -0
  173. pymmeans-0.1.0/tests/test_qdrg.py +151 -0
  174. pymmeans-0.1.0/tests/test_quantile.py +153 -0
  175. pymmeans-0.1.0/tests/test_r_benchmark.py +440 -0
  176. pymmeans-0.1.0/tests/test_r_parity.py +151 -0
  177. pymmeans-0.1.0/tests/test_ref_grid.py +138 -0
  178. pymmeans-0.1.0/tests/test_satterthwaite.py +195 -0
  179. pymmeans-0.1.0/tests/test_splines.py +273 -0
  180. pymmeans-0.1.0/tests/test_summary.py +101 -0
  181. pymmeans-0.1.0/tests/test_survey.py +180 -0
  182. pymmeans-0.1.0/tests/test_transforms.py +188 -0
  183. pymmeans-0.1.0/tests/test_trends.py +104 -0
  184. pymmeans-0.1.0/tests/test_utils.py +118 -0
  185. pymmeans-0.1.0/tests/test_vs_r.py +212 -0
  186. pymmeans-0.1.0/tests/test_weights.py +148 -0
@@ -0,0 +1,62 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.egg
11
+ .eggs/
12
+
13
+ # Virtual envs
14
+ .venv/
15
+ venv/
16
+ env/
17
+
18
+ # Test / coverage
19
+ .pytest_cache/
20
+ .coverage
21
+ .coverage.*
22
+ htmlcov/
23
+ .tox/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+
27
+ # Editors / OS
28
+ .idea/
29
+ .vscode/
30
+ .DS_Store
31
+ *.swp
32
+ *~
33
+ .Trash-*
34
+
35
+ # Jupyter checkpoint dirs
36
+ .ipynb_checkpoints/
37
+ */.ipynb_checkpoints/
38
+
39
+ # Docs build (mkdocs writes to ./site, sphinx to docs/_build)
40
+ docs/_build/
41
+ site/
42
+ .mkdocs_cache/
43
+
44
+ # Benchmarks output
45
+ benchmarks/r_results.csv
46
+ benchmarks/PERFORMANCE_REPORT.md
47
+
48
+ # Internal dev docs (kept locally; not published)
49
+ docs/pymmeans_project_plan.md
50
+ docs/v0_1_limits.md
51
+
52
+ # JSS manuscript (separate publication track)
53
+ paper/
54
+
55
+ # Internal-only test file (regression guards from a long iterative
56
+ # development cycle; kept locally for the maintainer, omitted from
57
+ # the public surface)
58
+ tests/test_audit_regressions.py
59
+
60
+ # Package-manager lockfile (this is a library, not an application;
61
+ # end-users install via pip with their own resolver)
62
+ uv.lock
@@ -0,0 +1,53 @@
1
+ # Changelog
2
+
3
+ All notable changes to `pymmeans` will be documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
6
+ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] — 2026-05-25
9
+
10
+ Initial release.
11
+
12
+ ### Added
13
+
14
+ - Reference-grid construction (`ref_grid`) and estimated marginal means
15
+ extraction (`emmeans`, `lsmeans`) for fitted `statsmodels` models,
16
+ `linearmodels` panel / IV results, and any user-supplied
17
+ `predict_fn(data) -> ndarray` callable.
18
+ - Pairwise contrasts (`pairs`), generic linear contrasts (`contrast`),
19
+ compact letter displays (`cld`), and pairwise p-value matrices
20
+ (`pwpm`).
21
+ - Multiplicity adjustments: Tukey HSD (exact studentised-range
22
+ integral), Dunnett (exact via the multivariate-_t_ CDF), Šidák,
23
+ Bonferroni, Holm, Benjamini–Hochberg FDR, and the generic `mvt`
24
+ integral.
25
+ - Small-sample mixed-model inference: `apply_satterthwaite`,
26
+ `apply_kenward_roger`, plus the six headline `pbkrtest`
27
+ equivalents (`kenward_roger_vcov`, `get_kr`, `ddf_lb`, `krmodcomp`,
28
+ `satmodcomp`, `pbmodcomp`).
29
+ - Response-scale back-transformation (`type="response"`) for
30
+ GLM-style links, including bias-adjusted estimates for log links.
31
+ - Bootstrap (`bootstrap_ci`, both parametric and case-resampling)
32
+ and permutation tests (`permutation_test`).
33
+ - Bayesian-posterior EMMs via `from_pymc` / `posterior_emmeans` /
34
+ `posterior_emm_summary` (optional `arviz` / `PyMC` integration).
35
+ - Survey-weighted EMMs via `from_survey` (Lumley-style designs).
36
+ - ML adapter (`from_predict`, `ml_emmeans`, `ml_pairs`,
37
+ `ml_contrast`) for tree ensembles, gradient-boosted models, neural
38
+ networks, and any other `.predict()`-capable estimator.
39
+ - `emtrends` for derivatives of the regression surface at focal points.
40
+ - `OrderedModel` (cumulative-link ordinal) and `MNLogit` (multinomial
41
+ logit) support.
42
+
43
+ ### Tested
44
+
45
+ - 858 unit tests against `statsmodels`, `linearmodels`,
46
+ `scikit-learn`, `xgboost`, `lightgbm`, `PyTorch`, `survey`, and
47
+ R-side reference values from `emmeans`, `lme4` + `lmerTest`,
48
+ `pbkrtest`, `marginaleffects`, and `survey`.
49
+ - R parity tolerances range from `atol < 1e-7` (survey-weighted
50
+ Gaussian) to `atol < 1e-3` (finite-difference Satterthwaite df);
51
+ the six `pbkrtest` equivalents match the R reference at
52
+ `atol < 1e-5` on identical $\hat\theta$ inputs.
53
+
@@ -0,0 +1,62 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use pymmeans in your research, please cite it as below."
3
+ title: "pymmeans: Estimated marginal means for Python"
4
+ abstract: >
5
+ pymmeans is a native-Python implementation of R's emmeans package
6
+ (Lenth 2024) for estimated marginal means (EMMs), pairwise and
7
+ custom contrasts, and multiplicity adjustments on fitted statistical
8
+ models. It supports statsmodels OLS / GLM / MixedLM / GEE / Cox /
9
+ BetaModel, the linearmodels panel and IV result classes, and any
10
+ prediction-only model with a ``.predict()`` method via a
11
+ beyond-R-parity ML adapter (g-computation / prediction-surface
12
+ averaging). The implementation uses an analytic Kronecker-product
13
+ marginalisation (no grid materialisation) so EMMs on designs with
14
+ 500K-row to 46M-row reference grids run in milliseconds where R
15
+ emmeans refuses or runs out of memory. Inference paths include
16
+ Wald, Satterthwaite, Kenward-Roger (Kackar-Harville), parametric
17
+ bootstrap, non-parametric case bootstrap with refit, permutation
18
+ testing with Phipson-Smyth correction, and Bayesian / posterior
19
+ draws.
20
+ authors:
21
+ - family-names: Turner
22
+ given-names: Jason
23
+ email: jason.s.turner@gmail.com
24
+ version: 0.1.0
25
+ date-released: 2026-05-25
26
+ license: GPL-3.0-or-later
27
+ repository-code: "https://github.com/jturner-uofl/pymmeans"
28
+ url: "https://github.com/jturner-uofl/pymmeans"
29
+ type: software
30
+ keywords:
31
+ - estimated marginal means
32
+ - emmeans
33
+ - least-squares means
34
+ - lsmeans
35
+ - linear models
36
+ - mixed-effects models
37
+ - generalized linear models
38
+ - multiplicity adjustment
39
+ - Satterthwaite degrees of freedom
40
+ - Kenward-Roger correction
41
+ - bootstrap inference
42
+ - g-computation
43
+ - statsmodels
44
+ - Python
45
+ references:
46
+ - type: article
47
+ title: "Least-squares means: the R package lsmeans"
48
+ authors:
49
+ - family-names: Lenth
50
+ given-names: Russell V.
51
+ year: 2016
52
+ journal: "Journal of Statistical Software"
53
+ volume: 69
54
+ issue: 1
55
+ doi: 10.18637/jss.v069.i01
56
+ - type: software
57
+ title: "emmeans: Estimated marginal means, aka least-squares means"
58
+ authors:
59
+ - family-names: Lenth
60
+ given-names: Russell V.
61
+ year: 2024
62
+ url: "https://cran.r-project.org/package=emmeans"