rdataframeggplot2

reorder the levels of a factor column in R to appear horizontally matching in two plots


i have a simulated data frame in R :

library(tidyverse)
library(ggstats)
library(patchwork)

set.seed(123)
likert_levels <- c(
  "1" = "Very  Dissatisfied",
  "2" = "Dissatisfied",
  "3" = "Neutral",
  "4" = "Satisfied",
  "5" = "Very  Satisfied")

df = data.frame(
  var = sample(c("yes", "no"), 50, replace = TRUE),
  A= sample(likert_levels, 50, replace = TRUE)) %>%
  mutate(across(everything(), as.factor)) %>%
  as_tibble() %>%
  mutate(across(-var, ~ factor(.x, levels = likert_levels)))

# starting plot (removed facets and ensured order of 'var' factor)
likert <- df %>%
  mutate(id = row_number()) %>%
  pivot_longer(-c(id,var), names_to="group") %>%
  pivot_wider(names_from=var) %>%
  gglikert(c(df$var))  # removed facet_rows=vars(group)

# get the order of years according to n
df2 <- df %>%
  mutate(id = row_number()) %>%
  pivot_longer(-c(id, var), names_to = "group") %>%
  count(group, var) %>%
  mutate(var = factor(var, levels = c("no", "yes"))) %>%
  arrange(var) %>%
  select(var) %>%
  distinct()

likert$data <- likert$data %>%
  mutate(.question = factor(.question, levels = c("no", "yes")))

# create the barplot (removed facets and ensured order of 'var' factor)
bar <- df %>%
  mutate(id = row_number()) %>%
  pivot_longer(-c(id, var), names_to = "group") %>%
  count(group, var) %>%
  mutate(var = factor(var, levels = c("no", "yes"))) %>%  # ensure 'no' comes first
  ggplot(aes(x = n, y = fct_reorder(var, n))) +
  geom_col() +
  geom_label(aes(label = n),
             color = "white", hjust = 1,
             fill = NA, label.size = 0) +
  labs(y = NULL) +  # removed facet_wrap
  likert$theme

# plot them side by side
likert + bar + plot_layout(widths = c(0.8, 0.2), guides = "collect") &
  theme(legend.position = "bottom")


resulting to

enter image description here

but i want to relevel or reoder the var column in order to show from top to bottom the "no" level and then the "yes" level in both the likert and the bar chart . How can i do it in R ?


Solution

  • Y-axes in ggplot start from the bottom. So if you want "no" at the top, it needs to be your last factor level, not your first.

    ## Instead of this
    var = factor(var, levels = c("no", "yes"))
    ## use this
    var = factor(var, levels = c("yes", "no"))
    

    Also, once your factors levels are ordered correctly, don't change them. y = fct_reorder(var, n) will reorder by the count, which is not what you want.