Search code examples
rggplot2likert

gglikert plot in R with perecentages


i have a data frame in R called df :

df
     Item Strongly Disagree Disagree    So So    Agree Strongly Agree
1  BRAZIL          13.33333 25.83333 15.83333 15.83333       29.16667
2 GERMANY          20.00000 20.00000 20.00000 10.00000       30.00000
3   ITALY          40.00000  0.00000 60.00000  0.00000        0.00000
4     USA           0.00000 16.25000 22.50000 28.75000       32.50000

i want to create a likert scale plot using ggplot2 or gglikert from ggstats. Specifically i want in the y axis to have the countries and in x axis the Likert levels.But i want to be sorted in an descending order according to very left proportions that are the combination (sum) of the two lower levels. (i.e Respectively the percentages on the very right in the sum of the two higher categories will be in an ascending order).

How can i do this in R using gglikert?

data :

dput(df)
structure(list(Item = c("BRAZIL", "GERMANY", "ITALY", "USA"), 
    `Strongly Disagree` = c(15, 20, 40, 13.3333333333333), Disagree = c(15, 
    40, 40, 20), `So So` = c(20, 10, 20, 13.3333333333333), Agree = c(15, 
    20, 0, 40), `Strongly Agree` = c(35, 10, 0, 13.3333333333333
    )), row.names = c(NA, -4L), class = "data.frame")

Solution

  • You can try

    library(tidyverse)
    library(ggstat)
    likert_levels <- c(
      "Strongly Disagree",
      "Disagree",
      "So So",
      "Agree",
      "Strongly Agree"
    )
    df %>% 
      pivot_longer(-c(Item)) %>% 
      mutate(value  = ifelse(Item == "USA" & name == "Strongly Agree", 14, value)) %>% 
      split(.$Item) %>% 
      map2_dfc(., names(.), ~tibble(rep(.x$name,times = round(.x$value))) %>% set_names(.y))  %>% 
      mutate(across(everything(), ~ factor(.x, levels = likert_levels))) %>% 
      gglikert(sort = "descending")
    

    enter image description here

    To sort by the lower bounds, you can use this answer: sort the gglikert chart based on the combination percentages in R

    df %>% 
      pivot_longer(-c(Item)) %>% 
      mutate(value  = ifelse(Item == "USA" & name == "Strongly Agree", 14, value)) %>% 
      split(.$Item) %>% 
      map2_dfc(., names(.), ~tibble(rep(.x$name,times = round(.x$value))) %>% set_names(.y))  %>% 
      mutate(across(everything(), ~ factor(.x, levels = likert_levels))) %>% 
      gglikert(sort = "ascending") +
      aes(y = reorder(.question,
                      ifelse(
                        .answer %in% c("Strongly disagree", "Disagree"),1, 0),
                      FUN = sum))