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

R语言ggplot2分组堆叠条形图添加样本量标签方法

解决方案

你需要拆分原数据中person列存储的样本量信息,再通过ggh4x包的分面自定义坐标轴功能,给每个分面的分类标签设置对应样本量,具体修改如下:

步骤1:新增样本量提取逻辑

在完成test数据框定义后,新增代码提取每个问题对应的GP、LW样本量,melt数据时保留该字段:

library(stringr)
library(reshape2)
# 提取每个问题的GP、LW样本量
test$gp_n <- str_extract(test$person, "GP \\(n = \\d+\\)")
test$lw_n <- str_extract(test$person, "LW \\(n = \\d+\\)")
# melt时保留新增的两个样本量字段
melted <- melt(test, id.vars = c("person", "gp_n", "lw_n"))

步骤2:修改绘图逻辑

安装加载ggh4x包用于自定义分面坐标轴,修改绘图代码的分面配置,新增自定义坐标轴标签的逻辑:

# 首次运行需先安装:install.packages("ggh4x")
library(ggh4x)
library(ggplot2)

melted$Response <- factor(melted$Response, c("Agree", "Neutral","Disagree"))

p = ggplot(melted, aes(x = cat, y = value, fill = Response))
p + geom_bar(stat = 'identity', position = 'stack') +
  geom_text(aes(label = paste0(value, "%")), position = position_stack(vjust = .5)) +
  ylab("Percentage of responses")+
  xlab("Population")+
  # 增加scales = "free_y"允许每个分面的y轴(原x轴)标签独立设置
  facet_grid(person~., scales = "free_y") + 
  # 给每个分面单独设置分类标签
  facetted_pos_scales(
    y = lapply(levels(melted$person), function(q) {
      person == q ~ scale_y_discrete(labels = c(
        "GP" = unique(melted[melted$person == q, ]$gp_n),
        "LW" = unique(melted[melted$person == q, ]$lw_n)
      ))
    })
  ) +
  scale_fill_manual(values = c("#488f31","#ffeb8a","#de425b")) + 
  theme(panel.background = element_rect(fill = 'white'),
        strip.text.y = element_text(angle = 0)) +
  coord_flip()

原理解释

  • 原生ggplot2的facet_grid默认所有分面共用坐标轴标签,ggh4x扩展包的facetted_pos_scales可以支持给每个分面单独设置坐标轴规则
  • 用正则提取person列里的样本量信息,避免手动输入样本量出现错漏
  • lapply批量生成每个分面的标签配置,比手动写5个分面规则更简洁,后续新增问题也不需要改这部分逻辑

内容的提问来源于stack exchange,提问作者Kushal Mohnot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 03:24:04