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:
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