如何用R的gglikert或ggplot2绘制分组因子为Y轴的李克特图?
用ggstats::gglikert()或ggplot2绘制分组在Y轴的李克特图
问题描述
我有如下结构的tibble数据框:
df # A tibble: 150 × 7 分组 q1 q2 q3 q4 q5 q6 <chr> <fct> <fct> <fct> <fct> <fct> <fct> 1 A 不同意 强烈不同意 强烈同意 同意 同意 强… 2 A 强烈不同意 同意 既不同意也不反对 既不同意也不反对 同意 强… 3 A 既不同意也不反对 不同意 强烈不同意 强烈同意 既… 既… 4 A 强烈不同意 既不同意也不反对 同意 不同意 强… 既… 5 B 强烈同意 强烈不同意 强烈同意 不同意 NA 同意 6 D 强烈不同意 既不同意也不反对 同意 强烈同意 既… 既… 7 B 既不同意也不反对 不同意 既不同意也不反对 既不同意也不反对 强… 既… 8 B 强烈不同意 强烈同意 既不同意也不反对 同意 既… 强… 9 A 既不同意也不反对 同意 强烈同意 强烈不同意 既… 同意 10 D 强烈同意 不同意 同意 不同意 同意 既… # ℹ 还有140行 # ℹ 使用 `print(n = ...)` 查看更多行
数据生成代码:
likert_levels <- c( "强烈不同意", "不同意", "既不同意也不反对", "同意", "强烈同意" ) df <- tibble( 分组 = sample(c("A", "B", "C", "D"), 150, replace = TRUE), q1 = sample(likert_levels, 150, replace = TRUE), q2 = sample(likert_levels, 150, replace = TRUE, prob = 5:1), q3 = sample(likert_levels, 150, replace = TRUE, prob = 1:5), q4 = sample(likert_levels, 150, replace = TRUE, prob = 1:5), q5 = sample(c(likert_levels, NA), 150, replace = TRUE), q6 = sample(likert_levels, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0)) ) %>% mutate(across(-分组, ~ factor(.x, levels = likert_levels))) df
我希望用ggstats包的gglikert()函数绘制该数据的图表,并且将分组因子设置为Y轴,请问怎么实现?
解决方案
方法一:直接使用ggstats::gglikert()实现
gglikert()默认将问题放在Y轴,要把分组移到Y轴,需要先调整数据结构,再指定参数:
- 重塑数据,让
分组成为李克特响应的分类项,原问题q1-q6作为分面维度:
library(tidyverse) library(ggstats) # 数据转置:先把宽格式转为长格式,再将分组转为列,最后重新转为长格式 df_long <- df %>% pivot_longer(-分组, names_to = "问题", values_to = "响应") %>% pivot_wider(names_from = "分组", values_from = "响应") %>% pivot_longer(-问题, names_to = "分组", values_to = "响应")
- 调用
gglikert(),指定y = 分组并设置orientation = "y":
gglikert(df_long, y = 分组, fill = 响应, facet = vars(问题)) + labs(title = "分组在Y轴的李克特图", y = "分组", x = "百分比") + theme_minimal()
运行后,每个子图对应一个问题,Y轴显示分组A/B/C/D,X轴为各响应选项的占比。
方法二:用ggplot2手动实现(更灵活可控)
如果不想依赖ggstats包,也可以手动计算占比后用ggplot2绘制:
- 计算每个分组、每个问题下各响应的百分比:
df_summary <- df %>% pivot_longer(-分组, names_to = "问题", values_to = "响应") %>% drop_na(响应) %>% # 剔除缺失值 count(分组, 问题, 响应) %>% group_by(分组, 问题) %>% mutate(百分比 = n / sum(n) * 100, # 计算标签位置,让百分比标签居中显示在条形内 标签位置 = cumsum(百分比) - 百分比 / 2)
- 绘制堆叠条形图,将分组放在Y轴:
ggplot(df_summary, aes(x = 百分比, y = 分组, fill = 响应)) + geom_col(position = "stack") + # 添加百分比标签 geom_text(aes(label = paste0(round(百分比), "%")), position = position_stack(vjust = 0.5)) + facet_wrap(~问题) + # 按问题分面 scale_fill_viridis_d(limits = likert_levels) + # 使用一致的颜色映射 labs(title = "分组在Y轴的李克特图", x = "百分比", y = "分组", fill = "响应选项") + theme_minimal()
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

