You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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轴,需要先调整数据结构,再指定参数:

  1. 重塑数据,让分组成为李克特响应的分类项,原问题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 = "响应")
  1. 调用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绘制:

  1. 计算每个分组、每个问题下各响应的百分比:
df_summary <- df %>%
  pivot_longer(-分组, names_to = "问题", values_to = "响应") %>%
  drop_na(响应) %>%  # 剔除缺失值
  count(分组, 问题, 响应) %>%
  group_by(分组, 问题) %>%
  mutate(百分比 = n / sum(n) * 100,
         # 计算标签位置,让百分比标签居中显示在条形内
         标签位置 = cumsum(百分比) - 百分比 / 2)
  1. 绘制堆叠条形图,将分组放在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:12:08