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

如何在R直方图中显示同意程度均值并保留图例标签

问题描述

需要在R中用ggplot2绘制的横向堆叠条形图上,为每个条目标注同意程度的加权均值:

  • 分值映射:Strongly agree=5,Somewhat agree=4,Neither agree nor disagree=3,Somewhat disagree=2,Strongly disagree=1
  • 要求不修改原始数据框Year2_likert_exhibits,同时保留图例标签,实现类似手动标注的均值显示效果。

以下是原始数据集及绘图代码:

Year2_likert_exhibits <-structure(list(Item = c("Were informative and educational", "Were easy to read", 
                                            "Covered topics I liked", "Were introduced in an informative way by staff", 
                                            "Were informative and educational", "Were easy to read", "Covered topics I liked", 
                                            "Were introduced in an informative way by staff", "Were informative and educational", 
                                            "Were easy to read", "Covered topics I liked", "Were introduced in an informative way by staff", 
                                            "Were informative and educational", "Were easy to read", "Covered topics I liked", 
                                            "Were introduced in an informative way by staff", "Were informative and educational", 
                                            "Were easy to read", "Covered topics I liked", "Were introduced in an informative way by staff"
), Evaluation = c("Strongly agree", "Strongly agree", "Strongly agree", 
                  "Strongly agree", "Somewhat agree", "Somewhat agree", "Somewhat agree", 
                  "Somewhat agree", "Neither agree nor disagree", "Neither agree nor disagree", 
                  "Neither agree nor disagree", "Neither agree nor disagree", "Somewhat disagree", 
                  "Somewhat disagree", "Somewhat disagree", "Somewhat disagree", 
                  "Strongly disagree", "Strongly disagree", "Strongly disagree", 
                  "Strongly disagree"), Value = c(125, 131, 134, 94, 37, 30, 28, 
                                                  34, 4, 1, 3, 33, 4, 4, 2, 4, 2, 3, 3, 6)), class = c("tbl_df", 
                                                                                                       "tbl", "data.frame"), row.names = c(NA, -20L))

####Impressions of Exhibits (Year 2) ####
Year2_likert_exhibits %>%
  ggplot()+
  geom_bar(aes(x = Item, y=Value, fill=reorder(Evaluation, -Value)), position="stack", stat="identity")+
  coord_flip() +
  ggtitle("Year 2 - Impressions of Exhibits")+
  ylab("Count")+
  xlab("The Exhibits...")+
  theme_minimal()+
  theme(legend.position="right",
        plot.title = element_text(size=22, hjust = 1),
        axis.title.y = element_text(size=14,face="bold"),
        axis.text.y = element_text(size = 12),
        axis.title.x = element_text(size = 12),
        axis.text.x = element_text(size = 12),
        panel.grid.major = element_blank(), #remove x axis grid
        panel.grid.minor = element_blank(),
        axis.line = element_line(colour = "black"))+
  guides(fill=guide_legend(title="Evaluation"))+
  scale_fill_brewer(palette="Spectral", direction = -1)+
  scale_x_discrete(labels = function(x) str_wrap(x, width = 17))
解决方案

步骤1:计算每个条目的加权均值

无需修改原数据框,通过dplyr分组计算每个Item的加权平均分值:

library(dplyr)
library(stringr)

mean_data <- Year2_likert_exhibits %>%
  group_by(Item) %>%
  summarize(
    # 映射Evaluation到对应分值
    score = case_match(
      Evaluation,
      "Strongly agree" ~ 5,
      "Somewhat agree" ~ 4,
      "Neither agree nor disagree" ~ 3,
      "Somewhat disagree" ~ 2,
      "Strongly disagree" ~ 1
    ),
    total_count = sum(Value),
    weighted_mean = sum(score * Value) / total_count,
    .groups = "drop"
  ) %>%
  # 匹配原图的Item顺序
  mutate(Item = factor(Item, levels = unique(Year2_likert_exhibits$Item)))

步骤2:在原图中添加均值标注

将计算好的均值数据传入geom_text,设置标注位置并格式化显示:

library(ggplot2)

Year2_likert_exhibits %>%
  ggplot()+
  geom_bar(aes(x = Item, y=Value, fill=reorder(Evaluation, -Value)), position="stack", stat="identity")+
  # 添加均值标注,偏移位置避免遮挡条形
  geom_text(data = mean_data, 
            aes(x = Item, y = total_count + 5, 
                label = sprintf("Mean: %.2f", weighted_mean)),
            size = 4, fontface = "bold")+
  coord_flip() +
  ggtitle("Year 2 - Impressions of Exhibits")+
  ylab("Count")+
  xlab("The Exhibits...")+
  theme_minimal()+
  theme(legend.position="right",
        plot.title = element_text(size=22, hjust = 1),
        axis.title.y = element_text(size=14,face="bold"),
        axis.text.y = element_text(size = 12),
        axis.title.x = element_text(size = 12),
        axis.text.x = element_text(size = 12),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.line = element_line(colour = "black"))+
  guides(fill=guide_legend(title="Evaluation"))+
  scale_fill_brewer(palette="Spectral", direction = -1)+
  scale_x_discrete(labels = function(x) str_wrap(x, width = 17))+
  # 扩展y轴范围,确保标注完全显示
  expand_limits(y = max(mean_data$total_count) + 10)

关键说明

  • 不修改原数据框:所有均值计算在独立的mean_data数据框中完成,原数据保持原样
  • 保留图例标签:原fill=reorder(Evaluation, -Value)的设置不变,图例的顺序和样式与原图一致
  • 标注位置:通过y = total_count + 5将均值放在条形右侧,expand_limits扩展y轴范围避免标注超出绘图区域
  • 均值格式化:用sprintf保留两位小数,提升可读性

内容的提问来源于stack exchange,提问作者Ryan Bruno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:50:27