pyemmeans 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.
- pyemmeans-0.1.0/LICENSE +20 -0
- pyemmeans-0.1.0/PKG-INFO +72 -0
- pyemmeans-0.1.0/README.md +72 -0
- pyemmeans-0.1.0/README_PYPI.md +38 -0
- pyemmeans-0.1.0/pyemmeans/__init__.py +248 -0
- pyemmeans-0.1.0/pyemmeans/adapters/__init__.py +11 -0
- pyemmeans-0.1.0/pyemmeans/adapters/base.py +11 -0
- pyemmeans-0.1.0/pyemmeans/adapters/qdrg.py +65 -0
- pyemmeans-0.1.0/pyemmeans/adapters/statsmodels.py +165 -0
- pyemmeans-0.1.0/pyemmeans/contrast.py +255 -0
- pyemmeans-0.1.0/pyemmeans/contrast_families.py +266 -0
- pyemmeans-0.1.0/pyemmeans/cov_reduce.py +41 -0
- pyemmeans-0.1.0/pyemmeans/effect_size.py +97 -0
- pyemmeans-0.1.0/pyemmeans/emmeans.py +445 -0
- pyemmeans-0.1.0/pyemmeans/emmip.py +275 -0
- pyemmeans-0.1.0/pyemmeans/emtrends.py +132 -0
- pyemmeans-0.1.0/pyemmeans/extras.py +127 -0
- pyemmeans-0.1.0/pyemmeans/factors.py +233 -0
- pyemmeans-0.1.0/pyemmeans/interface.py +41 -0
- pyemmeans-0.1.0/pyemmeans/internal_compat.py +292 -0
- pyemmeans-0.1.0/pyemmeans/joint.py +247 -0
- pyemmeans-0.1.0/pyemmeans/methods.py +234 -0
- pyemmeans-0.1.0/pyemmeans/options.py +55 -0
- pyemmeans-0.1.0/pyemmeans/pairwise_display.py +171 -0
- pyemmeans-0.1.0/pyemmeans/qdrg.py +184 -0
- pyemmeans-0.1.0/pyemmeans/rbind.py +115 -0
- pyemmeans-0.1.0/pyemmeans/ref_grid.py +441 -0
- pyemmeans-0.1.0/pyemmeans/regrid.py +140 -0
- pyemmeans-0.1.0/pyemmeans/summary.py +408 -0
- pyemmeans-0.1.0/pyemmeans/transforms.py +166 -0
- pyemmeans-0.1.0/pyemmeans/types.py +123 -0
- pyemmeans-0.1.0/pyemmeans/utils.py +212 -0
- pyemmeans-0.1.0/pyemmeans/wrappers.py +71 -0
- pyemmeans-0.1.0/pyemmeans.egg-info/PKG-INFO +72 -0
- pyemmeans-0.1.0/pyemmeans.egg-info/SOURCES.txt +52 -0
- pyemmeans-0.1.0/pyemmeans.egg-info/dependency_links.txt +1 -0
- pyemmeans-0.1.0/pyemmeans.egg-info/requires.txt +11 -0
- pyemmeans-0.1.0/pyemmeans.egg-info/top_level.txt +1 -0
- pyemmeans-0.1.0/pyproject.toml +53 -0
- pyemmeans-0.1.0/setup.cfg +4 -0
- pyemmeans-0.1.0/tests/test_compat_exports.py +19 -0
- pyemmeans-0.1.0/tests/test_effect_size_and_internal_exports.py +69 -0
- pyemmeans-0.1.0/tests/test_emmeans_core.py +75 -0
- pyemmeans-0.1.0/tests/test_emmip.py +65 -0
- pyemmeans-0.1.0/tests/test_extensions.py +73 -0
- pyemmeans-0.1.0/tests/test_extras.py +61 -0
- pyemmeans-0.1.0/tests/test_factors_and_meanchg.py +49 -0
- pyemmeans-0.1.0/tests/test_namespace_export_coverage.py +21 -0
- pyemmeans-0.1.0/tests/test_pwpm_pwpp.py +42 -0
- pyemmeans-0.1.0/tests/test_r_parity_fixtures.py +200 -0
- pyemmeans-0.1.0/tests/test_refgrid_advanced.py +67 -0
- pyemmeans-0.1.0/tests/test_regularize_and_accessors.py +53 -0
- pyemmeans-0.1.0/tests/test_weights_edgecases.py +69 -0
- pyemmeans-0.1.0/tests/test_wrappers_and_covreduce.py +56 -0
pyemmeans-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 29 June 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 pyemmeans contributors
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
SPDX-License-Identifier: GPL-3.0-or-later
|
|
20
|
+
|
pyemmeans-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyemmeans
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python rewrite of emmeans (estimated marginal means)
|
|
5
|
+
Author-email: Tuo Zhao <tourzhao@gatech.edu>
|
|
6
|
+
Maintainer-email: Tuo Zhao <tourzhao@gatech.edu>
|
|
7
|
+
License-Expression: GPL-3.0-or-later
|
|
8
|
+
Project-URL: Homepage, https://rvlenth.github.io/emmeans/
|
|
9
|
+
Keywords: estimated marginal means,least-squares means,statistics,post-hoc,linear models
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: numpy>=1.24
|
|
24
|
+
Requires-Dist: scipy>=1.10
|
|
25
|
+
Requires-Dist: pandas>=2.0
|
|
26
|
+
Requires-Dist: patsy>=0.5
|
|
27
|
+
Requires-Dist: statsmodels>=0.14
|
|
28
|
+
Requires-Dist: matplotlib>=3.8
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
32
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# pyemmeans
|
|
36
|
+
|
|
37
|
+
`pyemmeans` is a Python rewrite of core `emmeans` workflows for estimated marginal means (EMMs), contrasts, trends, and post-hoc inference.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install pyemmeans
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from pyemmeans import emmeans, pairs, ref_grid
|
|
49
|
+
|
|
50
|
+
# `fit` can be a supported statsmodels model result
|
|
51
|
+
rg = ref_grid(fit)
|
|
52
|
+
emm = emmeans(rg, "treatment")
|
|
53
|
+
print(emm.summary())
|
|
54
|
+
print(pairs(emm).summary(infer=(False, True)))
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Highlights
|
|
58
|
+
|
|
59
|
+
- Core EMM APIs: `ref_grid`, `emmeans`, `contrast`, `pairs`, `summary`, `confint`, `test`
|
|
60
|
+
- Trend and joint testing support: `emtrends`, `joint_tests`
|
|
61
|
+
- Multiple weight modes in `emmeans(..., weights=...)`
|
|
62
|
+
- Parity-oriented tests against R fixtures
|
|
63
|
+
|
|
64
|
+
## Project Notes
|
|
65
|
+
|
|
66
|
+
This package is a parity-oriented Python implementation inspired by the R `emmeans` ecosystem.
|
|
67
|
+
|
|
68
|
+
## Authorship and Attribution
|
|
69
|
+
|
|
70
|
+
- Python rewrite author: Tuo Zhao (`tourzhao@gatech.edu`)
|
|
71
|
+
- Original R `emmeans` package: developed by its R authors and contributors
|
|
72
|
+
- Full attribution details are included in `AUTHORS.md` in the source distribution.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# pyemmeans
|
|
2
|
+
|
|
3
|
+
Python rewrite of `emmeans` for estimated marginal means, contrasts, trends, and inference.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- Python help docs (generated from all R Rd pages + vignettes): [`docs/README.md`](docs/README.md)
|
|
8
|
+
- Reference index: [`docs/reference-index.md`](docs/reference-index.md)
|
|
9
|
+
- Guide index: [`docs/guide-index.md`](docs/guide-index.md)
|
|
10
|
+
|
|
11
|
+
## Authorship and attribution
|
|
12
|
+
|
|
13
|
+
- Python rewrite author: Tuo Zhao (`tourzhao@gatech.edu`)
|
|
14
|
+
- Original R `emmeans` package: developed by its R authors and contributors
|
|
15
|
+
- Full attribution details: [`AUTHORS.md`](AUTHORS.md)
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from pyemmeans import emmeans, ref_grid, pairs
|
|
21
|
+
|
|
22
|
+
rg = ref_grid(model_result)
|
|
23
|
+
emm = emmeans(rg, "treatment")
|
|
24
|
+
print(emm.summary())
|
|
25
|
+
print(pairs(emm).summary(infer=(False, True)))
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Implemented API (current)
|
|
29
|
+
|
|
30
|
+
- `ref_grid()`
|
|
31
|
+
- `emmeans()`, `lsmeans()`, `pmmeans()`
|
|
32
|
+
- `contrast()`, `pairs()`, `coef()`
|
|
33
|
+
- contrast families (`pairwise_emmc`, `tukey_emmc`, `trt_vs_ctrl_emmc`, ...)
|
|
34
|
+
- `summary()`, `confint()`, `test()`, `predict()`
|
|
35
|
+
- `regrid()`
|
|
36
|
+
- `eff_size()`
|
|
37
|
+
- `force_regular()`, `linfct()`
|
|
38
|
+
- `emtrends()`
|
|
39
|
+
- `joint_tests()`
|
|
40
|
+
- `pwpm()`, `pwpp()`
|
|
41
|
+
- `qdrg()`, `emmobj()`
|
|
42
|
+
- `rbind_emm_grid()`
|
|
43
|
+
- `emmip()`, `emmip_matplotlib()`
|
|
44
|
+
- factor utilities: `comb_facs()`, `split_fac()`, `add_grouping()`, `permute_levels()`
|
|
45
|
+
- wrapper aliases: `emm`, `lsmeans`, `lstrends`, `lsm`, `lsmobj`
|
|
46
|
+
`lsmip`
|
|
47
|
+
- covariate reducers: `make_meanint`, `meanint`, `make_symmint`, `symmint`
|
|
48
|
+
|
|
49
|
+
## Current model support
|
|
50
|
+
|
|
51
|
+
- `statsmodels` formula-based OLS/GLM
|
|
52
|
+
- `qdrg` custom wrapper models
|
|
53
|
+
|
|
54
|
+
## Performance check
|
|
55
|
+
|
|
56
|
+
- Run a reproducible local benchmark:
|
|
57
|
+
`python3 scripts/benchmark_emmeans.py`
|
|
58
|
+
|
|
59
|
+
## PyPI release
|
|
60
|
+
|
|
61
|
+
- Release checklist:
|
|
62
|
+
`docs/PYPI_RELEASE.md`
|
|
63
|
+
- One-command release helper:
|
|
64
|
+
`scripts/release_pypi.sh`
|
|
65
|
+
|
|
66
|
+
## Notes
|
|
67
|
+
|
|
68
|
+
- `nuisance` handling in `ref_grid()` is implemented with R-aligned behavior for `wt_nuis="equal"` and non-`equal` modes (`prop`, `outer`, `flat`, `cells` all follow proportional observed-frequency nuisance averaging, matching R internals), and nuisance factors that interact with other predictors are ignored.
|
|
69
|
+
- `counterfactuals` support is available in a baseline form (`actual_*` columns and `cf_grid` flow).
|
|
70
|
+
- `emmeans(..., weights=)` modes (`equal`, `proportional`, `outer`, `flat`, `cells`) plus `show.levels`, numeric vector weights, and matrix weights are covered by R parity fixtures and tests.
|
|
71
|
+
- The package is validated with smoke/integration tests in `tests/`.
|
|
72
|
+
- R-side baseline fixtures can be regenerated with `Rscript python-package/scripts/generate_r_fixtures.R`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# pyemmeans
|
|
2
|
+
|
|
3
|
+
`pyemmeans` is a Python rewrite of core `emmeans` workflows for estimated marginal means (EMMs), contrasts, trends, and post-hoc inference.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install pyemmeans
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from pyemmeans import emmeans, pairs, ref_grid
|
|
15
|
+
|
|
16
|
+
# `fit` can be a supported statsmodels model result
|
|
17
|
+
rg = ref_grid(fit)
|
|
18
|
+
emm = emmeans(rg, "treatment")
|
|
19
|
+
print(emm.summary())
|
|
20
|
+
print(pairs(emm).summary(infer=(False, True)))
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Highlights
|
|
24
|
+
|
|
25
|
+
- Core EMM APIs: `ref_grid`, `emmeans`, `contrast`, `pairs`, `summary`, `confint`, `test`
|
|
26
|
+
- Trend and joint testing support: `emtrends`, `joint_tests`
|
|
27
|
+
- Multiple weight modes in `emmeans(..., weights=...)`
|
|
28
|
+
- Parity-oriented tests against R fixtures
|
|
29
|
+
|
|
30
|
+
## Project Notes
|
|
31
|
+
|
|
32
|
+
This package is a parity-oriented Python implementation inspired by the R `emmeans` ecosystem.
|
|
33
|
+
|
|
34
|
+
## Authorship and Attribution
|
|
35
|
+
|
|
36
|
+
- Python rewrite author: Tuo Zhao (`tourzhao@gatech.edu`)
|
|
37
|
+
- Original R `emmeans` package: developed by its R authors and contributors
|
|
38
|
+
- Full attribution details are included in `AUTHORS.md` in the source distribution.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .contrast import coef, contrast, pairs, weights
|
|
4
|
+
from .contrast_families import (
|
|
5
|
+
consec_emmc,
|
|
6
|
+
del_eff_emmc,
|
|
7
|
+
dunnett_emmc,
|
|
8
|
+
eff_emmc,
|
|
9
|
+
helmert_emmc,
|
|
10
|
+
identity_emmc,
|
|
11
|
+
mean_chg_emmc,
|
|
12
|
+
nrmlz_emmc,
|
|
13
|
+
opoly_emmc,
|
|
14
|
+
pairwise_emmc,
|
|
15
|
+
poly_emmc,
|
|
16
|
+
revpairwise_emmc,
|
|
17
|
+
trt_vs_ctrl1_emmc,
|
|
18
|
+
trt_vs_ctrl_emmc,
|
|
19
|
+
trt_vs_ctrlk_emmc,
|
|
20
|
+
tukey_emmc,
|
|
21
|
+
wtcon_emmc,
|
|
22
|
+
)
|
|
23
|
+
from .cov_reduce import inverse, make_meanint, make_symmint, meanint, symmint
|
|
24
|
+
from .emmip import emmip, emmip_ggplot, emmip_lattice, emmip_matplotlib
|
|
25
|
+
from .emmeans import emmeans, pmmeans
|
|
26
|
+
from .emtrends import emtrends
|
|
27
|
+
from .effect_size import eff_size
|
|
28
|
+
from .extras import (
|
|
29
|
+
as_emm_list,
|
|
30
|
+
as_glht,
|
|
31
|
+
as_mcmc_emm_grid,
|
|
32
|
+
as_mcmc_emm_list,
|
|
33
|
+
as_mcmc_list_emm_grid,
|
|
34
|
+
as_mcmc_list_emm_list,
|
|
35
|
+
emm_example,
|
|
36
|
+
hpd_summary,
|
|
37
|
+
mvcontrast,
|
|
38
|
+
mvregrid,
|
|
39
|
+
)
|
|
40
|
+
from .factors import add_grouping, add_submodels, comb_facs, permute_levels, split_fac
|
|
41
|
+
from .interface import emm_basis, recover_data
|
|
42
|
+
from .internal_compat import (
|
|
43
|
+
all_vars,
|
|
44
|
+
aovlist_dffun,
|
|
45
|
+
cmpMM,
|
|
46
|
+
combine_terms,
|
|
47
|
+
diag,
|
|
48
|
+
emm_register,
|
|
49
|
+
emm_vignette,
|
|
50
|
+
get_excl,
|
|
51
|
+
get_offset,
|
|
52
|
+
hurdle_support,
|
|
53
|
+
my_vcov,
|
|
54
|
+
num_key,
|
|
55
|
+
std_link_labels,
|
|
56
|
+
zi_support,
|
|
57
|
+
)
|
|
58
|
+
from .joint import joint_tests, test_emm_grid
|
|
59
|
+
from .methods import as_emm_grid, emm_defaults, force_regular, linfct, update_emm_grid, vcov_emm_grid
|
|
60
|
+
from .options import emm_options, get_emm_option, with_emm_options
|
|
61
|
+
from .qdrg import emmobj, qdrg
|
|
62
|
+
from .pairwise_display import pwpm, pwpp
|
|
63
|
+
from .rbind import add_emm_grid, rbind_emm_grid
|
|
64
|
+
from .ref_grid import get_last_ref_grid, ref_grid
|
|
65
|
+
from .regrid import regrid
|
|
66
|
+
from .summary import confint_emm_grid, predict_emm_grid, summary_emm_grid
|
|
67
|
+
from .transforms import Link, make_link, make_tran
|
|
68
|
+
from .types import EmmBasisResult, EmmGrid, QDRGModel, RecoverDataResult
|
|
69
|
+
from .wrappers import emm, get_lsm_option, lsm, lsm_options, lsmobj, lsmeans, lsmip, lstrends
|
|
70
|
+
|
|
71
|
+
__version__ = "0.1.0"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def summary(object: EmmGrid, **kwargs):
|
|
75
|
+
return summary_emm_grid(object, **kwargs)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def confint(object: EmmGrid, **kwargs):
|
|
79
|
+
return confint_emm_grid(object, **kwargs)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test(object: EmmGrid, **kwargs):
|
|
83
|
+
return test_emm_grid(object, **kwargs)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def predict(object: EmmGrid, **kwargs):
|
|
87
|
+
return predict_emm_grid(object, **kwargs)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
__all__ = [
|
|
91
|
+
"EmmGrid",
|
|
92
|
+
"RecoverDataResult",
|
|
93
|
+
"EmmBasisResult",
|
|
94
|
+
"QDRGModel",
|
|
95
|
+
"ref_grid",
|
|
96
|
+
"get_last_ref_grid",
|
|
97
|
+
"emmeans",
|
|
98
|
+
"emm",
|
|
99
|
+
"lsmeans",
|
|
100
|
+
"lstrends",
|
|
101
|
+
"lsm",
|
|
102
|
+
"lsmip",
|
|
103
|
+
"lsmobj",
|
|
104
|
+
"emmip",
|
|
105
|
+
"emmip_ggplot",
|
|
106
|
+
"emmip_lattice",
|
|
107
|
+
"emmip_matplotlib",
|
|
108
|
+
"pmmeans",
|
|
109
|
+
"emtrends",
|
|
110
|
+
"contrast",
|
|
111
|
+
"pairs",
|
|
112
|
+
"coef",
|
|
113
|
+
"weights",
|
|
114
|
+
"pairwise_emmc",
|
|
115
|
+
"revpairwise_emmc",
|
|
116
|
+
"consec_emmc",
|
|
117
|
+
"tukey_emmc",
|
|
118
|
+
"trt_vs_ctrl_emmc",
|
|
119
|
+
"trt_vs_ctrl1_emmc",
|
|
120
|
+
"trt_vs_ctrlk_emmc",
|
|
121
|
+
"dunnett_emmc",
|
|
122
|
+
"eff_emmc",
|
|
123
|
+
"mean_chg_emmc",
|
|
124
|
+
"del_eff_emmc",
|
|
125
|
+
"identity_emmc",
|
|
126
|
+
"poly_emmc",
|
|
127
|
+
"opoly_emmc",
|
|
128
|
+
"helmert_emmc",
|
|
129
|
+
"nrmlz_emmc",
|
|
130
|
+
"wtcon_emmc",
|
|
131
|
+
"regrid",
|
|
132
|
+
"force_regular",
|
|
133
|
+
"summary",
|
|
134
|
+
"confint",
|
|
135
|
+
"test",
|
|
136
|
+
"predict",
|
|
137
|
+
"summary_emm_grid",
|
|
138
|
+
"confint_emm_grid",
|
|
139
|
+
"predict_emm_grid",
|
|
140
|
+
"test_emm_grid",
|
|
141
|
+
"joint_tests",
|
|
142
|
+
"eff_size",
|
|
143
|
+
"pwpm",
|
|
144
|
+
"pwpp",
|
|
145
|
+
"mvcontrast",
|
|
146
|
+
"mvregrid",
|
|
147
|
+
"comb_facs",
|
|
148
|
+
"split_fac",
|
|
149
|
+
"add_grouping",
|
|
150
|
+
"add_submodels",
|
|
151
|
+
"permute_levels",
|
|
152
|
+
"rbind_emm_grid",
|
|
153
|
+
"add_emm_grid",
|
|
154
|
+
"qdrg",
|
|
155
|
+
"emmobj",
|
|
156
|
+
"as_emm_list",
|
|
157
|
+
"as_glht",
|
|
158
|
+
"as_mcmc_emm_grid",
|
|
159
|
+
"as_mcmc_emm_list",
|
|
160
|
+
"as_mcmc_list_emm_grid",
|
|
161
|
+
"as_mcmc_list_emm_list",
|
|
162
|
+
"hpd_summary",
|
|
163
|
+
"emm_example",
|
|
164
|
+
"recover_data",
|
|
165
|
+
"emm_basis",
|
|
166
|
+
"all_vars",
|
|
167
|
+
"aovlist_dffun",
|
|
168
|
+
"cmpMM",
|
|
169
|
+
"combine_terms",
|
|
170
|
+
"diag",
|
|
171
|
+
"emm_register",
|
|
172
|
+
"emm_vignette",
|
|
173
|
+
"get_excl",
|
|
174
|
+
"get_offset",
|
|
175
|
+
"hurdle_support",
|
|
176
|
+
"my_vcov",
|
|
177
|
+
"num_key",
|
|
178
|
+
"std_link_labels",
|
|
179
|
+
"zi_support",
|
|
180
|
+
"vcov_emm_grid",
|
|
181
|
+
"linfct",
|
|
182
|
+
"as_emm_grid",
|
|
183
|
+
"update_emm_grid",
|
|
184
|
+
"emm_defaults",
|
|
185
|
+
"emm_options",
|
|
186
|
+
"get_emm_option",
|
|
187
|
+
"lsm_options",
|
|
188
|
+
"get_lsm_option",
|
|
189
|
+
"with_emm_options",
|
|
190
|
+
"make_meanint",
|
|
191
|
+
"meanint",
|
|
192
|
+
"make_symmint",
|
|
193
|
+
"symmint",
|
|
194
|
+
"inverse",
|
|
195
|
+
"Link",
|
|
196
|
+
"make_link",
|
|
197
|
+
"make_tran",
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
# R-style compatibility aliases (dot names)
|
|
201
|
+
_DOT_ALIASES = {
|
|
202
|
+
".all.vars": all_vars,
|
|
203
|
+
".aovlist.dffun": aovlist_dffun,
|
|
204
|
+
".cmpMM": cmpMM,
|
|
205
|
+
".combine.terms": combine_terms,
|
|
206
|
+
".diag": diag,
|
|
207
|
+
".emm_register": emm_register,
|
|
208
|
+
".emm_vignette": emm_vignette,
|
|
209
|
+
".get.excl": get_excl,
|
|
210
|
+
".get.offset": get_offset,
|
|
211
|
+
".hurdle.support": hurdle_support,
|
|
212
|
+
".my.vcov": my_vcov,
|
|
213
|
+
".num.key": num_key,
|
|
214
|
+
".std.link.labels": std_link_labels,
|
|
215
|
+
".zi.support": zi_support,
|
|
216
|
+
"get.lsm.option": get_lsm_option,
|
|
217
|
+
"lsm.options": lsm_options,
|
|
218
|
+
"make.meanint": make_meanint,
|
|
219
|
+
"make.symmint": make_symmint,
|
|
220
|
+
"make.tran": make_tran,
|
|
221
|
+
"as.emmGrid": as_emm_grid,
|
|
222
|
+
"as.emm_list": as_emm_list,
|
|
223
|
+
"as.glht": as_glht,
|
|
224
|
+
"as.mcmc.emmGrid": as_mcmc_emm_grid,
|
|
225
|
+
"as.mcmc.emm_list": as_mcmc_emm_list,
|
|
226
|
+
"as.mcmc.list.emmGrid": as_mcmc_list_emm_grid,
|
|
227
|
+
"as.mcmc.list.emm_list": as_mcmc_list_emm_list,
|
|
228
|
+
"hpd.summary": hpd_summary,
|
|
229
|
+
"pairwise.emmc": pairwise_emmc,
|
|
230
|
+
"revpairwise.emmc": revpairwise_emmc,
|
|
231
|
+
"consec.emmc": consec_emmc,
|
|
232
|
+
"tukey.emmc": tukey_emmc,
|
|
233
|
+
"trt.vs.ctrl.emmc": trt_vs_ctrl_emmc,
|
|
234
|
+
"trt.vs.ctrl1.emmc": trt_vs_ctrl1_emmc,
|
|
235
|
+
"trt.vs.ctrlk.emmc": trt_vs_ctrlk_emmc,
|
|
236
|
+
"dunnett.emmc": dunnett_emmc,
|
|
237
|
+
"eff.emmc": eff_emmc,
|
|
238
|
+
"mean_chg.emmc": mean_chg_emmc,
|
|
239
|
+
"del.eff.emmc": del_eff_emmc,
|
|
240
|
+
"identity.emmc": identity_emmc,
|
|
241
|
+
"poly.emmc": poly_emmc,
|
|
242
|
+
"opoly.emmc": opoly_emmc,
|
|
243
|
+
"helmert.emmc": helmert_emmc,
|
|
244
|
+
"nrmlz.emmc": nrmlz_emmc,
|
|
245
|
+
"wtcon.emmc": wtcon_emmc,
|
|
246
|
+
}
|
|
247
|
+
for _k, _v in _DOT_ALIASES.items():
|
|
248
|
+
globals()[_k] = _v
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .base import EmmAdapter
|
|
2
|
+
from .qdrg import emm_basis_qdrg, recover_data_qdrg
|
|
3
|
+
from .statsmodels import emm_basis_statsmodels, recover_data_statsmodels
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"EmmAdapter",
|
|
7
|
+
"recover_data_qdrg",
|
|
8
|
+
"emm_basis_qdrg",
|
|
9
|
+
"recover_data_statsmodels",
|
|
10
|
+
"emm_basis_statsmodels",
|
|
11
|
+
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Protocol
|
|
4
|
+
|
|
5
|
+
from ..types import EmmBasisResult, RecoverDataResult
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class EmmAdapter(Protocol):
|
|
9
|
+
def recover_data(self, model: Any, **kwargs: Any) -> RecoverDataResult: ...
|
|
10
|
+
|
|
11
|
+
def emm_basis(self, model: Any, trms: str, xlev: dict[str, list[Any]], grid, **kwargs: Any) -> EmmBasisResult: ...
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
7
|
+
from patsy import dmatrix
|
|
8
|
+
|
|
9
|
+
from ..transforms import make_link
|
|
10
|
+
from ..types import EmmBasisResult, QDRGModel, RecoverDataResult
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def recover_data_qdrg(model: QDRGModel, **kwargs: Any) -> RecoverDataResult:
|
|
14
|
+
formula = model.formula
|
|
15
|
+
lhs, rhs = [x.strip() for x in formula.split("~", 1)]
|
|
16
|
+
predictors = [c for c in model.data.columns if c in rhs or c == lhs or True]
|
|
17
|
+
# keep all columns to allow transformed expressions and at= usage
|
|
18
|
+
return RecoverDataResult(
|
|
19
|
+
data=model.data.copy(),
|
|
20
|
+
terms=formula,
|
|
21
|
+
predictors=[c for c in model.data.columns if c != lhs],
|
|
22
|
+
responses=[lhs],
|
|
23
|
+
call=None,
|
|
24
|
+
misc={},
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def emm_basis_qdrg(model: QDRGModel, trms: str, xlev: dict[str, list[Any]], grid: pd.DataFrame, **kwargs: Any) -> EmmBasisResult:
|
|
29
|
+
lhs, rhs = [x.strip() for x in trms.split("~", 1)]
|
|
30
|
+
Xdf = dmatrix(rhs, data=grid, return_type="dataframe")
|
|
31
|
+
X = np.asarray(Xdf, dtype=float)
|
|
32
|
+
|
|
33
|
+
coef = np.asarray(model.coef, dtype=float)
|
|
34
|
+
if coef.ndim > 1:
|
|
35
|
+
coef = coef.ravel()
|
|
36
|
+
p = X.shape[1]
|
|
37
|
+
if coef.size != p:
|
|
38
|
+
raise ValueError(f"Non-conforming coef length ({coef.size}) vs model matrix columns ({p})")
|
|
39
|
+
|
|
40
|
+
V = np.asarray(model.vcov, dtype=float)
|
|
41
|
+
if V.shape != (p, p):
|
|
42
|
+
raise ValueError(f"Non-conforming vcov shape {V.shape}; expected {(p, p)}")
|
|
43
|
+
|
|
44
|
+
def dffun(k: np.ndarray, dfargs: dict[str, Any]) -> float:
|
|
45
|
+
return float(dfargs["df"])
|
|
46
|
+
|
|
47
|
+
misc: dict[str, Any] = {}
|
|
48
|
+
if model.link:
|
|
49
|
+
misc["tran"] = make_link(model.link)
|
|
50
|
+
misc["inv_lbl"] = "response"
|
|
51
|
+
|
|
52
|
+
post_beta = None
|
|
53
|
+
if model.mcmc is not None:
|
|
54
|
+
post_beta = np.asarray(model.mcmc, dtype=float)
|
|
55
|
+
|
|
56
|
+
return EmmBasisResult(
|
|
57
|
+
X=X,
|
|
58
|
+
bhat=coef,
|
|
59
|
+
nbasis=np.array([[np.nan]]),
|
|
60
|
+
V=V,
|
|
61
|
+
dffun=dffun,
|
|
62
|
+
dfargs={"df": float(model.df)},
|
|
63
|
+
misc=misc,
|
|
64
|
+
post_beta=post_beta,
|
|
65
|
+
)
|