Skip to content

Effect sizes for ordinal models (emmeans backend), and effect-size fixes - #698

Open
jmgirard wants to merge 9 commits into
easystats:mainfrom
jmgirard:ordinal-latent-effect-sizes
Open

jmgirard wants to merge 9 commits into
easystats:mainfrom
jmgirard:ordinal-latent-effect-sizes

Conversation

@jmgirard

@jmgirard jmgirard commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

effectsize = "emmeans" now works for polr and clm models with predict = "latent" and a logit or probit link. Sigma is the SD of the latent error, pi / sqrt(3) (logit) or 1 (probit).

m <- MASS::polr(Sat ~ Infl + Type, weights = Freq, data = MASS::housing, Hess = TRUE)
estimate_contrasts(m, "Infl", predict = "latent", effectsize = "emmeans", backend = "emmeans")

This PR also fixes effectsize = "emmeans" for Gaussian models: effect sizes were in the wrong rows when factor levels were not sorted alphabetically, in the wrong columns with by, and always at the 95% level. Joint and omnibus tests with an effect size now give an informative error.

To decide:

  • Add effect size (Cohen's d) to estimate_contrasts #227 left the choice of sigma open, and Allow joint-test for factorial designs #501 kept effect sizes to models with a variance parameter. For logit and probit models the link fixes the latent SD, so I used it. If you'd rather keep effect sizes for Gaussian models only, I can drop the ordinal part and keep the fixes.
  • The marginaleffects backend is not covered, because it returns no latent-scale predictions for ordinal models (see the comments below).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Omnibus tests are not fully covered by the effect-size guard and require correction.

No open issues 🎉

1 file not reviewed
  • man/estimate_contrasts.Rd: Generated file
What changed in this PR

Adds emmeans latent-scale effect sizes for ordinal models and fixes effect-size row alignment, confidence limits, and grouping behavior.

Changes:

  • Supports logit/probit effect sizes for polr and clm.
  • Corrects contrast-to-effect-size ordering and CI handling.
  • Adds tests, documentation, NEWS, and a version bump.
File Summary
tests/​testthat/​test-ordinal.R Tests ordinal effect sizes and validation errors.
tests/​testthat/​test-estimate_contrasts_effectsize_order.R Tests ordering and confidence limits.
R/​get_emcontrasts.R Preserves contrast-row mappings.
R/​estimate_contrasts.R Forwards CI and rescaling options.
R/​estimate_contrasts_effectsize.R Implements ordinal effect sizes and validation.
NEWS.md Documents the changes.
man/​estimate_contrasts.Rd Updates reference documentation.
DESCRIPTION Bumps the development version.

Review effort: Lite

@jmgirard

Copy link
Copy Markdown
Contributor Author

#698 (review)

  • Omnibus tests and the effect-size guard: not changed. With backend = "marginaleffects", comparison = "omnibus" with effectsize = "marginal", "emmeans" or "boot" stops with "Effect sizes are not possible for joint or omnibus tests." With backend = "emmeans", comparison = "omnibus" already stops inside emmeans ("Contrast function 'omnibus.emmc' not found"), with or without effectsize, so no omnibus result reaches the effect sizes there (checked with lm(mpg ~ cyl * am + wt), by = "am").

@bwiernik

Copy link
Copy Markdown
Contributor

This should work for marginaleffects backend too

@jmgirard

jmgirard commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

The marginaleffects backend cannot give these effect sizes yet, because it does not return predictions on the latent scale for ordinal models. For polr, it only returns the probability of each category. Adding latent predictions there is a separate piece of work. Do you want it in this PR, or in a follow-up PR?

@jmgirard jmgirard changed the title Latent-scale effect sizes for ordinal models, and effect sizes on the rows of their own contrasts (emmeans backend) Effect sizes for ordinal models, and effect-size fixes Oct 21, 2026
@strengejacke

Copy link
Copy Markdown
Member

Or is it something that should be provided by the marginaleffects package in first instance?

@jmgirard jmgirard changed the title Effect sizes for ordinal models, and effect-size fixes Effect sizes for ordinal models (emmeans backend), and effect-size fixes Oct 21, 2026
@jmgirard
jmgirard force-pushed the ordinal-latent-effect-sizes branch from aed6528 to 371d45a Compare October 21, 2026 19:27
@jmgirard

Copy link
Copy Markdown
Contributor Author

Yes, I think marginaleffects needs to provide it first. I checked marginaleffects 1.0.0:

  • For polr, the only prediction type is "probs", so there is no latent scale to start from.
  • For clm, there is type = "linear.predictor", but it returns one value per threshold (the threshold minus the linear predictor), with 99999 for the top category. Contrasts of these values give the negative coefficients, so modelbased can rebuild latent contrasts for clm with a workaround. But then modelbased keeps code that belongs in marginaleffects, and polr still does not work.

My suggestion: this PR stays with the emmeans backend, and I open a feature request in marginaleffects for a latent prediction type for polr and clm. When marginaleffects has it, a follow-up PR adds these effect sizes to the marginaleffects backend. Is that OK with you?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants