Search code examples
rggplot2stringrlikert

Preserving Factor Order in scale_y_discrete with str_wrap in ggplot2 for Likert Data


I am trying to create a heat plot for Likert scale data using the likert package in R, and I want to wrap the y-axis labels using str_wrap to make them more readable. However, when I use str_wrap with scale_y_discrete, the order of the labels changes to alphabetical order instead of preserving the original order.

MRE with and without commenting out of scale_y_discrete(labels = function(x) str_wrap(x, width = 5)):

library(likert)
library(ggplot2)
library(stringr)
library(dplyr)

diamonds %>%
  select(cut) %>%
  as.data.frame() %>%
  likert() %>%
  plot(., type = "heat") +
  # scale_y_discrete(labels = function(x) str_wrap(x, width = 5))
  NULL

When I use scale_y_discrete(labels = str_wrap), the y-axis labels are wrapped correctly, but the order of the labels is changed to alphabetical order. I want to preserve the original order of the labels as in original_levels. Question:

How can I wrap the y-axis labels using str_wrap while preserving the original order in ggplot2?

I am quite certain that the issue is caused by the conversion of cut from a factor to a character class. However, I am unable to resolve this problem.

Any help or guidance on how to achieve this would be greatly appreciated!


Solution

  • IMHO the easiest way would be to wrap the labels before passing the data to likert():

    library(likert)
    library(stringr)
    library(dplyr)
    
    diamonds %>%
      select(cut) %>%
      as.data.frame() %>%
      mutate(
        across(cut, \(x) factor(
          x,
          levels = levels(x),
          labels = str_wrap(levels(x), width = 5)
        ))
      ) |>
      likert() %>%
      plot(., type = "heat")