rdataframeggplot2likert

Combine different gglikert plots and bar plots based on different criteria in R using ggplot2


i have a data frame called df with one grouping variable and two variables in likert scale:

set.seed(42)


likert_levels <- c("Strongly disagree", "Disagree", "Neutral", "Agree", "Strongly agree", NA)
df <- tibble(
  var = sample(c("Yes", "No"), 50, replace = TRUE),
  val1 = factor(sample(likert_levels, 50, replace = TRUE), levels = c("Strongly disagree", "Disagree", "Neutral", "Agree", "Strongly agree")),
  val2 = factor(sample(likert_levels, 50, replace = TRUE), levels = c("Strongly disagree", "Disagree", "Neutral", "Agree", "Strongly agree"))
  )

df
# A tibble: 50 × 3
   var   val1              val2          
   <chr> <fct>             <fct>         
 1 Yes   Agree             Agree         
 2 Yes   Strongly agree    Disagree      
 3 Yes   Agree             Disagree      
 4 Yes   Disagree          Neutral       
 5 No    Disagree          Strongly agree
 6 No    Neutral           Strongly agree
 7 No    Strongly disagree NA            
 8 No    Strongly agree    Neutral       
 9 Yes   Disagree          NA            
10 No    Disagree          Agree         
# ℹ 40 more rows
# ℹ Use `print(n = ...)` to see more rows

i want to gglikert it the two variables base on three conditions:

1) When the var=="Yes" 2) When the var == "No" 3) without the var

and at left of each of three likert chart with two percentage likert bars to be a bar horizontal plot with the count of each val1 and val2.

Something like this here but three times one upon each another with the three conditions as i described above,

How can i do it in R using ggplo2 and gglikert?


Solution

  • One option would be to use a plotting function to create the likert chart and the bar chart for each of the three combos which could then be combines using e.g. patchwork:

    library(tidyverse)
    library(ggstats)
    library(patchwork)
    
    plot_fun <- function(x, y) {
      .data <- df |>
        filter(var %in% x)
    
      p1 <- .data |>
        ggstats::gglikert(include = -var) +
        aes(y = reorder(.question,
          ifelse(
            .answer %in% c("Strongly disagree", "Disagree"),
            1, 0
          ),
          FUN = sum
        ), decreasing = TRUE) +
        labs(title = paste0("var = ", y))
    
      p2 <- .data %>%
        tidyr::pivot_longer(-var) |>
        filter(!is.na(value)) |> 
        mutate(
          name = reorder(name,
            ifelse(
              value %in% c("Strongly disagree", "Disagree"),
              1, 0
            ),
            FUN = sum
          )
        ) |>
        ggplot(aes(y = name)) +
        geom_bar(fill = "lightgrey")
      
      list(p1, p2)
    }
    
    .include <- list(No = "No", Yes = "Yes", All = c("Yes", "No"))
    
    purrr::imap(.include, plot_fun) |>
      purrr::reduce(c) |>
      wrap_plots(ncol = 2) +
      plot_layout(axes = "collect", guides = "collect", widths = c(.7, .3)) &
      labs(x = NULL, y = NULL) &
      theme(legend.position = "bottom")