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

R语言绘制Likert Scale图:运行代码后图表空白问题排查

问题描述

我想要绘制Likert量表数据图,横轴为百分比,纵轴为条目(Item),同时在每个条形中间显示百分比数值。但运行下方代码后图表完全空白,仅显示坐标轴标签。

Item <- c("EO1_PS", "EO1_OS", "EO2_PS", "EO2_OS")
SA <- c(0, 36, 0, 27)
A <- c(0, 64, 0, 73)
N <- c(0, 0, 0, 0)
D <- c(0, 0, 0, 0)
SD <- c(0, 0, 0, 0)
NAP <- c(100, 0, 100, 0)

# Creating Data Frame

df <- data.frame(Item, SA, A, N, D, SD, NAP)
print(df)

df <- df %>
  rename(
    "Strongly Agree" = SA,
    "Agree" = A,
    "Neutral" = N,
    "Disagree" = D,
    "Strongly Disagree" = SD,
    "Not Applicable" = NAP
  )

likert <- df %>
  gather(response, percent, -Item)
likert

ind_order <- likert %>
  filter(response == "Not Applicable") %>
  arrange(desc(percent))

lik <- likert %>
  mutate(Item = factor(Item, levels = ind_order, ordered = TRUE)) %>
  mutate(response = factor(response,
    levels = c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable"), ordered = TRUE,
    labels = c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable")
  )) %>
  mutate(percent = ifelse(response %in% c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable"), percent))

# Plot

gg <- ggplot()
gg <- gg + geom_hline(yintercept = 0)

gg <- gg + geom_text(
  data = filter(lik, percent > 0),
  aes(x = Item, y = percent, group = response, label = paste(percent * 100, "%")),
  position = "stack", hjust = 1, size = 2.5, color = "white"
)

gg <- gg + scale_x_discrete(expand = c(0, .75))
gg <- gg + scale_fill_manual(
  values = c("#4393c3", "#92c5de", "#b2182b", "gray"),
  drop = FALSE
)
gg <- gg + scale_y_continuous(
  expand = c(0, .10),
  breaks = seq(.35, 1, .25),
  limits = c(.35, .95)
)
gg <- gg + coord_flip()
gg <- gg + theme_bw()
gg <- gg + theme(axis.ticks = element_blank())
gg <- gg + theme(panel.border = element_blank())
gg <- gg + theme(panel.grid.major.y = element_blank())
gg <- gg + theme(panel.grid = element_blank())
gg
错误分析
  • 管道符不完整:所有%>都应为%>%,导致数据处理流程完全失效
  • 缺失条形图层:仅添加了水平线和文本图层,没有绘制条形的geom_col/geom_bar,因此看不到核心的条形元素
  • 数值与坐标轴范围不匹配:数据中percent是整数(如36、100),但scale_y_continuous设置的范围是0.35-0.95,数值完全不在可见区间内
  • 因子水平设置错误:ind_order是筛选后的数据框,不能直接作为Item的因子水平,需提取其中的Item列
  • 填充色数量不匹配:scale_fill_manual仅提供4种颜色,但response有6个类别,颜色数量不足
  • 文本位置逻辑错误:coord_flip交换坐标轴后,geom_text的x/y映射和位置调整逻辑混乱,且未使用堆叠位置对齐文本
修正后的代码
library(tidyverse)

# 原始数据
Item <- c("EO1_PS", "EO1_OS", "EO2_PS", "EO2_OS")
SA <- c(0, 36, 0, 27)
A <- c(0, 64, 0, 73)
N <- c(0, 0, 0, 0)
D <- c(0, 0, 0, 0)
SD <- c(0, 0, 0, 0)
NAP <- c(100, 0, 100, 0)

# 创建数据框并重命名列
df <- data.frame(Item, SA, A, N, D, SD, NAP) %>%
  rename(
    "Strongly Agree" = SA,
    "Agree" = A,
    "Neutral" = N,
    "Disagree" = D,
    "Strongly Disagree" = SD,
    "Not Applicable" = NAP
  )

# 转换为长格式数据
likert <- df %>%
  gather(response, percent, -Item)

# 设置Item的排序规则(按Not Applicable的百分比降序)
ind_order <- likert %>%
  filter(response == "Not Applicable") %>%
  arrange(desc(percent)) %>%
  pull(Item) # 提取Item列作为因子水平

# 数据预处理:转换因子类型,将百分比转为小数
lik <- likert %>%
  mutate(Item = factor(Item, levels = ind_order, ordered = TRUE)) %>%
  mutate(response = factor(response,
    levels = c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable"),
    ordered = TRUE
  )) %>%
  mutate(percent = percent / 100) # 转为小数适配坐标轴范围

# 绘制图表
ggplot(lik, aes(x = Item, y = percent, fill = response)) +
  geom_col(position = "stack") + # 添加堆叠条形图层
  geom_text(
    data = filter(lik, percent > 0),
    aes(label = paste0(round(percent * 100), "%")),
    position = position_stack(vjust = 0.5), # 文本居中显示在条形内
    size = 2.5, color = "white"
  ) +
  scale_fill_manual(
    values = c("#4393c3", "#92c5de", "#fddbc7", "#d6604d", "#b2182b", "gray"), # 匹配6个响应类别的颜色
    drop = FALSE
  ) +
  scale_y_continuous(
    expand = c(0, 0),
    breaks = seq(0, 1, 0.25),
    limits = c(0, 1),
    labels = scales::percent_format() # 自动生成百分比坐标轴标签
  ) +
  coord_flip() +
  theme_bw() +
  theme(
    axis.ticks = element_blank(),
    panel.border = element_blank(),
    panel.grid = element_blank()
  ) +
  labs(x = "条目", y = "百分比")
关键修改说明
  • 补全所有管道符%>%,确保数据处理流程正常运行
  • 添加geom_col(position = "stack")绘制核心的堆叠条形
  • 将百分比数值转为小数,让数据适配0-1的坐标轴范围
  • 用pull(Item)提取排序后的条目列表,修正Item的因子水平设置
  • 补充scale_fill_manual的颜色数量,匹配所有6个响应类别
  • 调整geom_text的位置为position_stack(vjust = 0.5),让文本居中显示在条形内部
  • 使用scales::percent_format()自动生成百分比坐标轴标签,简化格式设置

内容的提问来源于stack exchange,提问作者Aydan Pakta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:25:01