Search code examples
rdataframeggplot2

Horizontally match levels of two different plots in R


i have a data frame in r called df:

set.seed(123)
likert_levels <- c(
  "1" = "Very  Dissatisfied",
  "2" = "Dissatisfied",
  "3" = "Neutral",
  "4" = "Satisfied",
  "5" = "Very  Satisfied")
df = data.frame(
  year = sample(c(2023, 2022, 2020, 2018), 50, replace = TRUE),
  A = sample(likert_levels, 50, replace = TRUE),
  B = sample(likert_levels, 50, replace = TRUE),
  C = sample(likert_levels, 50, replace = TRUE))%>%
  mutate(across(everything(),as.factor))%>%
  as_tibble()%>%
  mutate(across(-year, ~ factor(.x, levels = likert_levels)))
df

the likert chart i can do it like this :

mutate(df, id=row_number()) |>
  pivot_longer(-c(id, year), names_to="group") |>
  pivot_wider(names_from=year) |>
  gglikert(c(`2023`, `2022`, `2020`, `2018`), 
         facet_rows=vars(group))

but in this setup i want also the bar plot of number of observations per year to be plotted and with patchwork library to bind them. But i want to horizontally match each year of likert with each year of bar plot . How can i do it in R ?


Solution

  • Not sure what's exactly the issue. But here is one option to achieve your desired result:

    library(patchwork)
    library(tidyverse)
    library(ggstats)
    
    p2 <- mutate(df, id = row_number()) |>
      pivot_longer(-c(id, year), names_to = "group") |>
      count(group, year) |>
      ggplot(aes(n, year)) +
      geom_col() +
      geom_label(aes(label = n), color = "white", hjust = 1, fill = NA, label.size = 0) +
      #scale_y_discrete(breaks = NULL)
      facet_wrap(~group, ncol = 1, strip.position = "right") +
      labs(y = NULL) +
      # Use the same theme as p1
      p1$theme
    
    # p1 is the gglikert chart
    p1 + p2 +
      plot_layout(guides = "collect", widths = c(2, 1)) &
      theme(legend.position = "bottom")