strengejacke/ggeffects

Plotting ordinal logistic predicted effects on latent scale of ordinal outcome?

Closed this issue · 3 comments

When estimating an ordinal logistic the output conventionally appears as something like:

image

However, a more interpretable output could be to have the ordinal logistic predictions generated on the latent scale of the outcome.

For example...

The brms package has a parameter for the conditional_effects() function "categorical = F" which "Indicates if effects of categorical or ordinal models should be shown in terms of probabilities of response categories"

https://paul-buerkner.github.io/brms/reference/conditional_effects.brmsfit.html
https://discourse.mc-stan.org/t/interpretation-of-conditional-effects-in-cumulative-models-using-posterior-linpred/28679

The effects package has a parameter for latent = TRUE, where "if TRUE, effects in a proportional-odds logit model are computed on the scale of the latent response; if FALSE (the default) effects are computed as individual-level probabilities and logits."

https://www.rdocumentation.org/packages/effects/versions/4.2-2/topics/effect

Could this be something that could be accomplished with ggeffects?

You're talking about something like these two different type of plots?

library(effects)
#> Loading required package: carData
#> lattice theme set by effectsTheme()
#> See ?effectsTheme for details.
library(MASS)
options(contrasts = c("contr.treatment", "contr.poly"))
m <- polr(Sat ~ Infl + Type + Cont, weights = Freq, data = housing)

plot(effects::Effect(c("Infl", "Type"), m, latent = TRUE))
#> 
#> Re-fitting to get Hessian

plot(effects::Effect(c("Infl", "Type"), m, latent = FALSE))
#> 
#> Re-fitting to get Hessian

Created on 2024-04-29 with reprex v2.1.0

In this particular case, there's no predict() type to get the predictions on the latent scale. I must check how to achieve this using emmeans or marginaleffects, so I could make this available for these options in ggeffects (i.e. ggemmeans() and ggaverage()). And I must check how other packages handle predict(), like ordinal::clm(), and their options with emmeans or marginaleffects.

Ok, this is the current progress. Works for ggeffect() only at the moment.

library(ggeffects)
library(effects)
#> Loading required package: carData
#> lattice theme set by effectsTheme()
#> See ?effectsTheme for details.
library(MASS)
options(contrasts = c("contr.treatment", "contr.poly"))
m <- polr(Sat ~ Infl + Type + Cont, weights = Freq, data = housing)

ggeffect(m, c("Infl", "Type"), latent = TRUE)
#> # Predicted log-odds of Sat
#> 
#> Type: Tower
#> 
#> Infl   | Predicted |       95% CI
#> ---------------------------------
#> Low    |      0.18 |  0.09,  0.27
#> Medium |      0.75 |  0.52,  0.98
#> High   |      1.47 |  1.19,  1.75
#> 
#> Type: Apartment
#> 
#> Infl   | Predicted |       95% CI
#> ---------------------------------
#> Low    |     -0.39 | -0.63, -0.15
#> Medium |      0.17 | -0.14,  0.49
#> High   |      0.90 |  0.55,  1.24
#> 
#> Type: Atrium
#> 
#> Infl   | Predicted |       95% CI
#> ---------------------------------
#> Low    |     -0.19 | -0.49,  0.12
#> Medium |      0.38 |  0.01,  0.76
#> High   |      1.10 |  0.71,  1.50
#> 
#> Type: Terrace
#> 
#> Infl   | Predicted |       95% CI
#> ---------------------------------
#> Low    |     -0.91 | -1.21, -0.61
#> Medium |     -0.34 | -0.71,  0.02
#> High   |      0.38 | -0.02,  0.77

effects::Effect(c("Infl", "Type"), m, latent = TRUE)
#> 
#> Re-fitting to get Hessian
#> 
#>  Infl*Type effect
#>         Type
#> Infl         Tower  Apartment     Atrium    Terrace
#>   Low    0.1801421 -0.3922081 -0.1860445 -0.9108728
#>   Medium 0.7465358  0.1741857  0.3803492 -0.3444791
#>   High   1.4689611  0.8966110  1.1027746  0.3779462
#> 
#> Thresholds:
#>  Low|Medium Medium|High 
#>  -0.4961353   0.6907083


ggeffect(m, c("Infl", "Type"), latent = TRUE) |> plot()

effects::Effect(c("Infl", "Type"), m, latent = TRUE) |> plot()
#> 
#> Re-fitting to get Hessian

Created on 2024-04-30 with reprex v2.1.0