ggplot绘制分组条形图(Dodged Bar Chart)的技术问题咨询
ggplot绘制分组条形图(Dodged Bar Chart)的技术问题咨询
嗨,我来帮你搞定这个分组条形图的问题~你遇到的核心卡点其实是数据格式不匹配:ggplot绘制这种按类别分组的图表需要「长格式数据」,而你当前的数据集是「宽格式」(每个种族单独占一列),只要把数据转成长格式,y轴的问题和填充的问题就都迎刃而解了!
先理清楚你的数据逻辑
假设你的原始数据大概是这样的(模拟县级疫苗接种数据,比如接种率):
# 模拟你的原始宽格式数据 county_vaccine <- data.frame( county = c("县A", "县B"), 白人接种率 = c(78, 72), 黑人接种率 = c(65, 60), 拉丁裔接种率 = c(60, 57) )
这种格式下,每个种族是单独的列,没办法直接让ggplot识别为填充的分组,所以需要把它转成「长格式」——也就是新增一个种族列,把所有种族名称放进去,再新增一个接种指标列(比如接种率/接种人数,这就是你要的y轴)。
用tidyr重塑数据(正确的「旋转」方式)
别用基础R的t()转置啦,那会把数据变成矩阵,还得手动改列名,特别麻烦。用tidyverse里的pivot_longer()函数,一步就能把宽格式转成长格式:
# 先加载tidyverse包(包含ggplot2和tidyr) library(tidyverse) # 重塑数据:把所有种族列转成长格式 long_data <- county_vaccine %>% pivot_longer( cols = -county, # 除了county列之外的所有列都要转 names_to = "种族", # 新的分组列名(用来填充的) values_to = "接种率" # 新的数值列名(这就是y轴) )
运行完之后,你的数据就变成了这样的长格式:
| county | 种族 | 接种率 |
|---|---|---|
| 县A | 白人接种率 | 78 |
| 县A | 黑人接种率 | 65 |
| 县A | 拉丁裔接种率 | 60 |
| 县B | 白人接种率 | 72 |
| 县B | 黑人接种率 | 60 |
| 县B | 拉丁裔接种率 | 57 |
绘制分组条形图
现在数据格式对了,ggplot就能轻松画出你要的分组(dodged)条形图了:
ggplot(long_data, aes(x = county, y = 接种率, fill = 种族)) + geom_bar(stat = "identity", position = "dodge", width = 0.7) + # position="dodge"就是分组效果 labs(title = "两县不同种族疫苗接种率对比", x = "县", y = "接种率", fill = "种族") + theme_minimal()
position = "dodge":让同县的不同种族条形并排显示(就是你要的dodged效果)fill = 种族:用种族列来区分条形颜色- y轴就是我们刚刚生成的
接种率(或者你实际的接种指标,比如接种人数)
关于你提到的「转置后没法把第一行当列名」的问题
你之前用基础转置t()的方式会把数据转换成矩阵,而且原始的第一行(县名)会变成行名,处理起来很繁琐。而用pivot_longer()是专门为这种宽转长的场景设计的,不需要手动调整列名,直接就能生成ggplot需要的结构化数据,比基础转置方便太多啦!
备注:内容来源于stack exchange,提问作者rachlbaart
相关产品推荐
相关产品推荐

