R语言制作分组箱线图遇阻:需实现两类误差指标按月份并排展示
该需求完全可实现,核心调整逻辑是将当前宽格式的数据集转换为长格式:当前数据中两个SIR误差指标分别占据独立列,属于宽格式结构;而并排分组箱线图需要所有误差值存储在同一列,通过单独的分类字段标记每个值所属的指标类型,才能触发boxplot的分组并排逻辑。以下提供两种可直接运行的调整方案:
方案1:基于base R(和你现有代码体系完全兼容,无需安装第三方包)
- 利用base R自带的
stack()函数快速完成宽格式转长格式:# 提取两个目标误差列,自动合并为长格式,新增ind列标记值所属的指标 plot_data <- stack(dataset[, c("ER_SIR_100", "ER_SIR_50")]) # 重复月份字段2次,匹配长格式下两倍的观测长度,和误差值一一对应 plot_data$month <- rep(dataset$MESN, times = 2) # 确保月份为因子类型,避免排序错位 plot_data$month <- as.factor(plot_data$month) - 自定义箱子位置,实现月内并排、月间留空的视觉效果,再调整绘图参数:
# 计算箱子放置位置:单月内两个箱子保持间距,不同月份组之间留更大空隙 n_months <- nlevels(plot_data$month) box_positions <- unlist(lapply(1:n_months, \(i) c((i-1)*2 + 1, (i-1)*2 + 1.6))) boxplot( # 公式规则:误差值 ~ 月份 * 指标类型,自动识别分组 values ~ month * ind, data = plot_data, at = box_positions, # 应用自定义的箱子位置 main = 'SIR误差按月份分组对比', ylab = 'Error', xlab = 'Mês', las = 1, # 为两个指标分配固定填充色 col = c("#4e79a7", "#f28e2b"), # 调整箱子宽度,避免过挤 boxwex = 0.5 ) # 重新设置x轴刻度位置,匹配自定义的箱子排布 axis(1, at = unlist(lapply(1:n_months, \(i) (i-1)*2 + 1.3)), labels = levels(plot_data$month)) # 手动添加图例,对应两个指标的颜色 legend( "topright", legend = c("ER_SIR_100", "ER_SIR_50"), fill = c("#4e79a7", "#f28e2b"), bty = "n" )
方案2:基于ggplot2(出图样式更易调整,无需手动处理位置间距)
如果日常绘图习惯用ggplot2,代码逻辑会更简洁,不需要手动计算箱子位置:
# 加载需要的包 library(ggplot2) library(tidyr) # 宽格式转长格式,提前处理月份因子类型 plot_data <- dataset %>% mutate(MESN = as.factor(MESN)) %>% pivot_longer( cols = c(ER_SIR_100, ER_SIR_50), names_to = "indicator", values_to = "error" ) # 绘制分组并排箱线图 ggplot(plot_data, aes(x = MESN, y = error, fill = indicator)) + # position_dodge自动实现同月份下两个箱子并排 geom_boxplot(position = position_dodge(0.8)) + labs( title = "SIR误差按月份分组对比", x = "Mês", y = "Error", fill = "误差指标" ) + theme_bw() + theme( axis.text.x = element_text(angle = 0, hjust = 0.5) # 匹配原有las=1的水平标签效果 )
注意:如果绘图时月份顺序不符合预期,先确认
MESN字段已经被转为因子类型,并通过factor()的levels参数指定正确的月份顺序,避免轴标签错位。
内容的提问来源于stack exchange,提问作者Arthur
相关产品推荐
相关产品推荐

