如何在同一轴绘制多变量箱线图?R代码报错求解
箱线图展示sa2种群不同温度处理下两代繁殖力差异
分析sa2种群常温(ambient)和热激(heat shocked)个体的繁殖力数据,对比brood 1和brood 2的幼虫数量,发现常温组brood 1幼虫数多于brood 2,热激组则相反。尝试用箱线图展示该趋势时,基础R代码报错,ggplot2代码无法同时生成两组箱线图。
原始数据
| ID | temp | brood 1 | brood 2 | brood avg |
|---|---|---|---|---|
| sa2 | ambient | 20 | 5 | 12.5 |
| sa2 | ambient | 21 | 10 | 15.5 |
| sa2 | shocked | 19 | 22 | 20.5 |
| sa2 | shocked | 24 | 26 | 25 |
| sa2 | ambient | 20 | 15 | 17.5 |
| sa2 | ambient | 28 | 23 | 25.5 |
| sa2 | shocked | 21 | 31 | 26 |
| sa2 | shocked | 22 | 21 | 21.5 |
错误原因分析
基础R代码错误
原代码报错Error in as.data.frame.default(data) : cannot coerce class ‘"formula"’ to a data.frame,原因有三点:
boxplot()不支持直接传入多个独立公式作为参数;- 子集索引未指定数据框(
ID == "sa2"需改为fecundity.df.grouped$ID == "sa2"); - 列名不匹配(原始数据列名为
temp,代码中用temperature)。
ggplot2代码错误
原代码无法生成两组箱线图,因为:
aes()中不能同时指定两个y变量(brood.1..和brood.2..);- ggplot2要求数据为长格式(每一行对应一个观测值),而原始数据是宽格式(brood 1和brood 2为独立列),需先转换格式。
解决方案
第一步:导入并整理数据
先将原始数据读入R,统一列名并转换为长格式:
# 导入原始数据 fecundity.df <- data.frame( ID = rep("sa2", 8), temp = c("ambient", "ambient", "shocked", "shocked", "ambient", "ambient", "shocked", "shocked"), brood1 = c(20,21,19,24,20,28,21,22), brood2 = c(5,10,22,26,15,23,31,21), brood_avg = c(12.5,15.5,20.5,25,17.5,25.5,26,21.5) ) # 转换为长格式(适配ggplot2和更简洁的基础R代码) fecundity_long <- reshape(fecundity.df, varying = c("brood1", "brood2"), v.names = "larvae", timevar = "brood", times = c("brood 1", "brood 2"), direction = "long")
基础R正确箱线图代码
方式1:按温度×繁殖代次分组展示
boxplot(larvae ~ temp * brood, data = fecundity_long, col = c("lightgreen", "darkgreen", "lightgreen", "darkgreen"), xlab = "温度处理 × 繁殖代次", ylab = "幼虫数量", main = "sa2种群不同处理下的繁殖力差异")
方式2:分面板展示不同温度处理
boxplot(larvae ~ brood | temp, data = fecundity_long, col = c("lightgreen", "darkgreen"), xlab = "繁殖代次", ylab = "幼虫数量", main = "sa2种群不同温度处理的繁殖力", layout = c(2,1)) # 2列1行的面板布局
方式3:不转换格式,直接传入向量列表
# 提取各组数据 ambient_brood1 <- fecundity.df$brood1[fecundity.df$temp == "ambient"] ambient_brood2 <- fecundity.df$brood2[fecundity.df$temp == "ambient"] shocked_brood1 <- fecundity.df$brood1[fecundity.df$temp == "shocked"] shocked_brood2 <- fecundity.df$brood2[fecundity.df$temp == "shocked"] # 绘制箱线图 boxplot(list(ambient_brood1, ambient_brood2, shocked_brood1, shocked_brood2), col = c("lightgreen", "darkgreen", "lightgreen", "darkgreen"), names = c("常温-brood 1", "常温-brood 2", "热激-brood 1", "热激-brood 2"), xlab = "处理组", ylab = "幼虫数量", main = "sa2种群繁殖力对比")
ggplot2正确箱线图代码
方式1:x轴为温度处理,繁殖代次用颜色区分
library(ggplot2) ggplot(fecundity_long, aes(x = temp, y = larvae, fill = brood)) + geom_boxplot(position = position_dodge(width = 0.8), width = 0.7) + labs(x = "温度处理", y = "幼虫数量", title = "sa2种群不同处理下两代繁殖力差异") + scale_fill_manual(values = c("lightgreen", "darkgreen")) + theme_bw()
方式2:x轴为繁殖代次,温度处理用颜色区分
ggplot(fecundity_long, aes(x = brood, y = larvae, fill = temp)) + geom_boxplot(position = position_dodge(width = 0.8), width = 0.7) + labs(x = "繁殖代次", y = "幼虫数量", title = "sa2种群不同处理下两代繁殖力差异") + scale_fill_manual(values = c("lightblue", "orange")) + theme_bw()
内容的提问来源于stack exchange,提问作者J Phelps
相关产品推荐
相关产品推荐

