使用 ggplot2 根据 R 中的类别排列李克特量表 ggplot

问题描述 投票:0回答:1

我在 R 中有以下数据框,称为 df :

df
# A tibble: 90 × 3
# Groups:   item [18]
   item  Response          Percentage
   <chr> <fct>                  <dbl>
 1 A     Very Dissatisfied       25  
 2 A     Dissatisfied            25  
 3 A     Average                 33.3
 4 A     Satisfied               11.1
 5 A     Very Satisfied          55.6
 6 B     Very Dissatisfied       25  
 7 B     Dissatisfied            25  
 8 B     Average                 44.4
 9 B     Satisfied               25  
10 B     Very Satisfied          55.6
# ℹ 80 more rows
# ℹ Use `print(n = ...)` to see more rows

这是一个李克特量表响应数据框,下一个是 ggplot2 生成的图:

response_mapping <- c("Very Dissatisfied" = 1,
                      "Dissatisfied" = 2,
                      "Average" = 3,
                      "Satisfied" = 4,
                      "Very Satisfied" = 5)

# Apply the mapping and calculate the sign
data_f_sum <- df %>% 
  ungroup() %>% 
  mutate(res.sgn = sign(response_mapping[as.character(Response)] - 3)) %>% 
  summarise(sum.prcnt = sum(Percentage),
            .by = c(item, res.sgn))

data_f_sum
likert_levels =  c("Very Dissatisfied", 
                   "Dissatisfied" ,
                   "Average" ,
                   "Satisfied", 
                   "Very Satisfied")

df = df%>%
  mutate(Response = factor(Response , levels = likert_levels))


ggplot(data = df, 
       aes(Percentage, item, fill = Response)) +
  geom_col(position = position_likert()) +
  scale_x_continuous(labels = ggstats::label_percent_abs()) +
  geom_label(data = data_f_sum,
             aes(label = sprintf("%.1f", sum.prcnt), y = item, x = res.sgn),
             alpha = 0.3, inherit.aes = FALSE) +
  coord_cartesian(xlim = c(-1, 1)) +
  scale_fill_brewer(type = "div", palette = "RdYlGn") +
  theme_bw()+ 
  theme(legend.position = "bottom") 


我想要整个改变情节:

1)首先按照“非常不满意”类别排序,然后按照“不满意”类别从低到高排序

我可以在这个 ggplot 中用 R 来完成这个任务吗?有什么帮助吗?

数据可以在这里找到:

structure(list(item = c("A", "A", "A", "A", "A", "B", "B", "B", 
"B", "B", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "E", 
"E", "E", "E", "E", "F", "F", "F", "F", "F", "G", "G", "G", "G", 
"G", "H", "H", "H", "H", "H", "I", "I", "I", "I", "I", "J", "J", 
"J", "J", "J", "K", "K", "K", "K", "K", "L", "L", "L", "L", "L", 
"M", "M", "M", "M", "M", "N", "N", "N", "N", "N", "O", "O", "O", 
"O", "O", "P", "P", "P", "P", "P", "Q", "Q", "Q", "Q", "Q", "R", 
"R", "R", "R", "R"), Response = structure(c(1L, 2L, 3L, 4L, 5L, 
1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 
2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 
3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 
4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 
5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 
1L, 2L, 3L, 4L, 5L), levels = c("Very Dissatisfied", "Dissatisfied", 
"Average", "Satisfied", "Very Satisfied"), class = "factor"), 
    Percentage = c(25, 25, 33.3, 11.1, 55.6, 25, 25, 44.4, 25, 
    55.6, 25, 25, 22.2, 33.3, 44.4, 25, 25, 33.3, 11.1, 55.6, 
    25, 22.2, 11.1, 11.1, 55.6, 25, 25, 44.4, 11.1, 44.4, 25, 
    25, 11.1, 33.3, 55.6, 25, 25, 33.3, 22.2, 44.4, 25, 25, 11.1, 
    33.3, 55.6, 25, 25, 22.2, 22.2, 55.6, 25, 25, 11.1, 11.1, 
    77.8, 25, 25, 11.1, 33.3, 55.6, 25, 25, 33.3, 25, 66.7, 25, 
    25, 33.3, 11.1, 55.6, 25, 11.1, 25, 33.3, 55.6, 25, 25, 22.2, 
    22.2, 55.6, 25, 22.2, 22.2, 11.1, 44.4, 25, 11.1, 22.2, 11.1, 
    55.6)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -90L), groups = structure(list(item = c("A", 
"B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", 
"O", "P", "Q", "R"), .rows = structure(list(1:5, 6:10, 11:15, 
    16:20, 21:25, 26:30, 31:35, 36:40, 41:45, 46:50, 51:55, 56:60, 
    61:65, 66:70, 71:75, 76:80, 81:85, 86:90), ptype = integer(0), class = c("vctrs_list_of", 
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -18L), .drop = TRUE))


r dataframe ggplot2 likert
1个回答
0
投票

这里的关键是将“Item”列按照正确的顺序转换为因子变量。

library(tidyr)
#make the data wide format to sore
newdf <- df %>% pivot_wider("item", values_from = "Percentage", names_from = "Response")

#use the order function to sort the first 2 columns
sortorder <- order(newdf$`Very Dissatisfied`, newdf$Dissatisfied, decreasing = FALSE)

#now convert the ID column "item" into a factor in the correct order
df$item<-factor(df$item,  levels=newdf$item[sortorder])
© www.soinside.com 2019 - 2024. All rights reserved.