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
相关产品推荐
相关产品推荐

