使用ggplot2绘制百分比组成facet_grid时遇美学映射错误求助
解决ggplot2绘制facet_grid时的"Aesthetics长度不匹配"错误
嘿,我看你在绘制堆叠百分比条形图时碰到了美学映射长度不匹配的报错,咱们来拆解问题并修复它:
问题根源
你代码里的核心问题是错误地创建了Abundance和Clade向量,导致它们的长度和你用来绘图的子集(比如file.29)行数完全不匹配:
- 你把整个
X_clade里的A/B/C/E/F列所有值都拼接成了一个超长的Clade向量,又基于所有数据的总和计算了Abundance,这俩向量的长度是nrow(X_clade)*5(比如24行的话就是120个值)。 - 但你的子集
file.29只有对应特定天数的个体行数,ggplot要求x/y/fill这些美学映射的长度必须和数据行数一致,所以就抛出了那个错误。
另外,你没必要把数据拆成多个子集分开绘图,用长格式数据+分面就能一步搞定。
修复步骤
1. 把宽格式数据转成ggplot需要的长格式
ggplot绘制堆叠图需要长格式数据:每一行对应一个个体的一个分支的数值。我们可以用tidyr和dplyr来处理(如果没装的话先运行install.packages(c("tidyr", "dplyr"))):
library(tidyr) library(dplyr) library(ggplot2) library(scales) library(wesanderson) # 先处理原始数据:去掉无数据的B/F列和你不需要的D列,转成长格式 X_clade_long <- X_clade %>% select(-B, -F, -D) %>% # 删除没用的列 # 把A/C/E列转成长格式:列名变Clade,值变value pivot_longer(cols = c(A, C, E), names_to = "Clade", values_to = "value") %>% # 按每个个体计算分支百分比(解决总和不等于100%的问题) group_by(ind) %>% mutate(Abundance = 100 * value / sum(value)) %>% ungroup()
这里按每个个体内部计算百分比,确保每个个体的分支总和是100%,完美解决你提到的“总和接近但不等于100%”的问题。
2. 用长格式数据直接绘制分面图
不需要拆分数据成file.29/file.53/file.65,直接用facet_grid就能按天数和温度分面:
p <- ggplot(X_clade_long, aes(x = ind, y = Abundance, fill = Clade)) + geom_bar(position = "fill", stat = "identity") + # 把y轴改成百分比格式 scale_y_continuous(labels = percent_format()) + # 用wesanderson的调色板,你之前加载过这个包 scale_fill_manual(values = wes_palette("GrandBudapest1")) + theme( panel.background = element_blank(), panel.border = element_rect(fill = NA), panel.grid.minor = element_blank(), axis.text.x = element_text(colour = "black", size = 11), axis.text.y = element_text(colour = "black", size = 11), axis.title = element_blank() ) + # 按days(行)和temperature(列)分面,x轴自适应每个分面的个体 facet_grid(days ~ temperature, scales = "free_x") # 显示图形 print(p)
额外小建议
- 建议保留fill的图例(去掉
guides(fill=FALSE)),这样看图形的人能清楚每个颜色对应的分支。 - 这种长格式数据的处理方式比你之前拆分数据再拼接的方法更简洁,也更容易维护和修改。
内容的提问来源于stack exchange,提问作者Homère
相关产品推荐
相关产品推荐

