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

如何在R的gglikert中按‘同意+非常同意’总和排序分面子图?

基于gglikert实现分面子图按“同意类选项总和”排序

使用ggstats库的模拟数据(代码见下文),需要让gglikert生成的每个分面子图,按照**"Strongly agree"(非常同意)和"Agree"(同意)的总和**进行排序,具体实现方法如下:

可复现模拟数据

library(ggstats)
library(dplyr)
library(ggplot2)

# 定义李克特量表水平
likert_levels <- c(
  "Strongly disagree",
  "Disagree",
  "Neither agree nor disagree",
  "Agree",
  "Strongly agree"
)

set.seed(42)
df <-
  tibble(
    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(everything(), ~ factor(.x, levels = likert_levels)))

# 添加分组变量
df_group <- df
df_group$group1 <- sample(c("A", "B"), 150, replace = TRUE)
df_group$group2 <- sample(c("a", "b", "c"), 150, replace = TRUE)

实现排序的核心思路

要让分面内的子图按同意类选项总和排序,需先计算每个分面组下各问题的同意总和,重新定义问题变量的因子水平顺序后,再传入gglikert。

场景1:仅按列分面(facet_cols = group1)

# 1. 转换为长格式,计算每个group1分组下各问题的同意总和
rank_df <- df_group |>
  pivot_longer(q1:q6, names_to = "question", values_to = "response") |>
  filter(!is.na(response)) |>
  group_by(group1, question) |>
  summarise(agree_total = sum(response %in% c("Agree", "Strongly agree")), .groups = "drop") |>
  # 按group1分组,对同意总和降序排序,确定问题顺序
  group_by(group1) |>
  arrange(desc(agree_total)) |>
  mutate(question_order = factor(question, levels = unique(question)))

# 2. 将原数据的问题变量转换为排序后的因子
df_group_sorted <- df_group |>
  pivot_longer(q1:q6, names_to = "question", values_to = "response") |>
  left_join(rank_df |> select(group1, question, question_order), by = c("group1", "question")) |>
  pivot_wider(names_from = question, values_from = response) |>
  mutate(across(q1:q6, ~ factor(.x, levels = likert_levels)))

# 3. 绘制排序后的likert图
gglikert(df_group_sorted,
         q1:q6,
         facet_cols = vars(group1),
         labels_size = 3)

场景2:按行和列分面(facet_rows = group2, facet_cols = group1)

# 1. 计算每个group1+group2组合下各问题的同意总和
rank_df_2 <- df_group |>
  pivot_longer(q3:q6, names_to = "question", values_to = "response") |>
  filter(!is.na(response)) |>
  group_by(group1, group2, question) |>
  summarise(agree_total = sum(response %in% c("Agree", "Strongly agree")), .groups = "drop") |>
  # 按group1+group2分组,对同意总和降序排序
  group_by(group1, group2) |>
  arrange(desc(agree_total)) |>
  mutate(question_order = factor(question, levels = unique(question)))

# 2. 转换原数据的问题变量为排序后的因子
df_group_sorted_2 <- df_group |>
  pivot_longer(q3:q6, names_to = "question", values_to = "response") |>
  left_join(rank_df_2 |> select(group1, group2, question, question_order), by = c("group1", "group2", "question")) |>
  pivot_wider(names_from = question, values_from = response) |>
  mutate(across(q3:q6, ~ factor(.x, levels = likert_levels)))

# 3. 绘制排序后的likert图
gglikert(df_group_sorted_2,
         q3:q6,
         facet_cols = vars(group1),
         facet_rows = vars(group2),
         labels_size = 3) +
  scale_x_continuous(
    labels = label_percent_abs(),
    expand = expansion(0, .2)
  )

补充说明

  • 代码默认按同意总和降序排序,若需升序,将arrange(desc(agree_total))改为arrange(agree_total)即可;
  • 计算总和时也可改用百分比(如agree_pct = mean(response %in% c("Agree", "Strongly agree"))),排序逻辑一致。

内容的提问来源于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.14 12:47:16