Skip to content

Instantly share code, notes, and snippets.

@andrewheiss
Created June 21, 2024 19:30
Show Gist options
  • Save andrewheiss/9b76fcaf784f97e7198b83d04f563053 to your computer and use it in GitHub Desktop.
Save andrewheiss/9b76fcaf784f97e7198b83d04f563053 to your computer and use it in GitHub Desktop.
library(MASS)
library(tidyverse)
library(marginaleffects)
library(palmerpenguins)

# Make a categorical weight column
penguins <- penguins |> 
  drop_na(sex) |> 
  mutate(weight_cat = cut(
    body_mass_g, breaks = 3, ordered_result = TRUE, 
    labels = c("Light", "Medium", "Heavy"))
  )

# Predict weight based on sex
mod <- polr(weight_cat ~ sex, data = penguins, Hess = TRUE)

# Predictions
preds_exact <- predictions(mod, by = "sex")
preds_exact
#> 
#>   Group    sex Estimate Std. Error     z Pr(>|z|)     S  2.5 % 97.5 %
#>  Light  male     0.2348     0.0314  7.47   <0.001  43.5 0.1732  0.296
#>  Light  female   0.6517     0.0360 18.11   <0.001 241.1 0.5812  0.722
#>  Medium male     0.4868     0.0327 14.89   <0.001 164.2 0.4227  0.551
#>  Medium female   0.2888     0.0296  9.77   <0.001  72.4 0.2308  0.347
#>  Heavy  male     0.2784     0.0337  8.26   <0.001  52.6 0.2124  0.344
#>  Heavy  female   0.0595     0.0125  4.77   <0.001  19.0 0.0351  0.084
#> 
#> Columns: group, sex, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high 
#> Type:  probs
# Predictions through bootstrapping
preds_bootstrapped <- predictions(mod, by = "sex") |> 
  inferences(method = "rsample", R = 500)
preds_bootstrapped
#> 
#>   Group    sex Estimate  2.5 % 97.5 %
#>  Light  male     0.2348 0.1717 0.2995
#>  Light  female   0.6517 0.5781 0.7135
#>  Medium male     0.4868 0.4279 0.5502
#>  Medium female   0.2888 0.2351 0.3482
#>  Heavy  male     0.2784 0.2135 0.3558
#>  Heavy  female   0.0595 0.0397 0.0824
#> 
#> Columns: group, sex, estimate, conf.low, conf.high 
#> Type:  probs
# These aren't actually posterior draws, but posteriordraws() can extract the bootstrapped samples 
preds_long <- posteriordraws(preds_bootstrapped)

# Extract labels from exact predictions
preds_labs <- preds_exact |>
  arrange(desc(group)) |> 
  group_by(sex) |> 
  mutate(
    y_end = cumsum(estimate),
    y_start = lag(y_end, default = 0),
    y = y_end - ((y_end - y_start) / 2),
    y_lab = glue::glue("{round(estimate, 2)} ({round(std.error, 2)})")
  )

# Plot
ggplot(preds_long, aes(x = as.numeric(drawid), y = draw)) + 
  geom_area(aes(fill = group), position = position_stack()) + 
  geom_label(
    data = preds_labs, aes(x = 250, y = y, label = y_lab), 
    fill = scales::alpha("white", 0.4), label.size = 0, fontface = "bold"
  ) +
  labs(y = "Cumulative predicted probability", fill = "Weight category") +
  facet_wrap(vars(sex))

Created on 2024-06-21 with reprex v2.1.0

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