基于ggplot创建可动态切换横竖的水平堆叠条形图及显示N标签
解决方案
你的代码存在几个核心问题:
Food和Machinery列是带%的字符类型,无法完成数值堆叠计算- 水平条形图需要调整坐标轴映射或使用
coord_flip()实现 - 要显示
Total(N标签)需要保留该列数据并单独添加标注
以下是修正后的完整代码,包含动态切换横竖布局、正确堆叠条形、显示N标签的功能:
library(tidyverse) # 修正原始数据(补全US的Food值缺失的%) proba <- data.frame(PartnerName = c("China", "Brazil", "Argentina", "UE", "US"), Food = c("12%","22%","36%","40%","51%"), Machinery = c("91%","78%","64%","60%","49%"), Total = c(26,28,43,34,25)) # 数据预处理:将百分比字符串转为数值,保留Total列用于标注 graph_data <- proba %>% mutate(across(c(Food, Machinery), ~ as.numeric(str_remove(., "%")))) %>% pivot_longer(-c(PartnerName, Total)) # 定义布局切换参数(TRUE=水平条形,FALSE=垂直条形) is_horizontal <- TRUE # 绘制图表 ggplot(graph_data, aes(x = if(is_horizontal) value else PartnerName, y = if(is_horizontal) PartnerName else value, fill = name)) + geom_col(width = 0.9, position = "stack") + # 添加N标签(显示Total数值) geom_text(data = proba, aes(x = 100, y = PartnerName, label = paste0("N=", Total)), inherit.aes = FALSE, hjust = 1.1) + # 动态调整坐标轴标签 labs(x = if(is_horizontal) "百分比" else "合作伙伴", y = if(is_horizontal) "合作伙伴" else "百分比", fill = "类别") + theme_minimal()
关键细节说明:
- 数据修正:把带
%的字符型百分比转为数值,同时补全了US的Food值缺失的% - 动态布局:通过
is_horizontal参数一键切换横竖布局,无需重复编写多份代码 - N标签实现:直接调用原始数据的Total列,在条形外侧添加
N=xx标注,用inherit.aes = FALSE避免继承主图层的映射规则 - 堆叠优化:用
geom_col()替代geom_bar(stat="identity"),功能一致但写法更直观
如果习惯用coord_flip()实现水平布局,也可以用以下写法:
is_horizontal <- TRUE ggplot(graph_data, aes(x = PartnerName, y = value, fill = name)) + geom_col(width = 0.9, position = "stack") + geom_text(data = proba, aes(x = PartnerName, y = 105, label = paste0("N=", Total)), inherit.aes = FALSE) + labs(x = "合作伙伴", y = "百分比", fill = "类别") + theme_minimal() + {if(is_horizontal) coord_flip()}
内容的提问来源于stack exchange,提问作者potro
相关产品推荐
相关产品推荐

