使用mapply批量绘图时split数据出错的问题求助
问题分析与解决方案
核心问题点
- DGV数据拆分错误:原代码拆分DGV数据时参数格式错误,未按
Pesticide和DGV.Type双维度正确拆分,导致拆分后的列表结构不符合预期。 - 绘图函数未使用传入的子集数据:函数内直接调用原始数据集
ToxDat_subset和DGVDat_subset,而非mapply传入的拆分后子集x和y,因此所有水平线会出现在每幅图中,标题也无法对应子集。 - 列表长度不匹配:原拆分后L1(2个元素)和L2(错误拆分后的结构)长度不一致,无法一一配对生成4幅目标图表。
修正后代码
# 加载必要包 library(ggplot2) # 数据拆分 # 1. 拆分Tox数据,为每个农药复制一份以对应Fresh/Marine类型,得到4个元素的列表 L1 <- split(ToxDat_subset, ToxDat_subset$Pesticide) L1_expanded <- c(L1$Ametryn, L1$Ametryn, L1$Diuron, L1$Diuron) names(L1_expanded) <- c("Ametryn_Fresh", "Ametryn_Marine", "Diuron_Fresh", "Diuron_Marine") # 2. 正确拆分DGV数据:按Pesticide和DGV.Type双维度拆分 L2 <- split(DGVDat_subset, list(DGVDat_subset$Pesticide, DGVDat_subset$DGV.Type)) # 调整L2的名称顺序,与L1_expanded对应 L2 <- L2[c("Ametryn.Fresh", "Ametryn.Marine", "Diuron.Fresh", "Diuron.Marine")] names(L2) <- names(L1_expanded) # 修正绘图函数:使用传入的子集x(Tox数据)和y(DGV数据) myplot <- function(x, y) { # 提取当前图表的农药和DGV类型 pesticide <- unique(x$Pesticide) dgv_type <- unique(y$DGV.Type) ggplot(x, aes(x = factor(Phyla), y = Conc_ug)) + geom_boxplot(color = "dark gray", fill = 'dark gray', alpha = 0.1) + geom_jitter(aes(shape = Pathway), height = .3, width = .3, size = 1.5) + scale_y_continuous(trans = 'log10') + theme_bw() + scale_x_discrete(guide = guide_axis(angle = 45)) + theme( panel.border = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(color = "black"), text = element_text(size = 14), axis.title.x = element_text(margin = unit(c(5, 0, 0, 0), "mm")), axis.title.y = element_text(margin = unit(c(0, 5, 0, 0), "mm")) ) + # 使用传入的y子集绘制水平线,按Protection.Level区分线型 geom_hline(data = y, aes(yintercept = Conc_ug, linetype = Protection.Level)) + scale_linetype_discrete(name = "Protection Level") + labs( x = "Phyla", y = "Log10 Concentration (µg/L)", title = paste(pesticide, dgv_type), subtitle = "Marine ecotox data", caption = "Source: Citation, Reliability ?? " ) } # 生成图表列表:L1_expanded和L2长度均为4,一一对应 Lplots <- mapply(FUN = myplot, x = L1_expanded, y = L2, SIMPLIFY = FALSE) # 保存图表 vnames <- paste0(names(Lplots), '.png') mapply(ggsave, plot = Lplots, filename = vnames, width = 30, units = 'cm')
关键修正说明
- 数据拆分对齐:将Tox数据的每个农药子集复制一次,确保与DGV的4个(农药+类型)子集一一对应,解决列表长度不匹配问题。
- 函数内使用子集数据:绘图时完全依赖传入的
x和y子集,确保每幅图只显示对应农药的Tox数据和对应农药+类型的DGV水平线。 - 恢复水平线的线型区分:重新启用
linetype映射,让不同Protection Level的水平线有区分,同时添加图例说明。
内容的提问来源于stack exchange,提问作者CatN
相关产品推荐
相关产品推荐

