ggplot2分组均值计算异常:如何按年-月分组统计儒略日绘图
问题根因
现有代码的核心逻辑错误出在分组步骤:仅使用group_by(Month)按月份分组时,mean()计算的是筛选后全量数据中同月份的跨年份全局均值,没有拆分年份维度,得到的均值完全不符合「分年份、分月份统计平均儒略日」的需求。
另外原代码还存在两个隐性语法问题:一是列名julian day带空格,直接写在函数内会被R识别为两个独立变量触发报错;二是如果需要按Subsite筛选,原代码的filter步骤没有加入对应判断条件。
修正方案
- 调整分组逻辑,分组时同时传入
Year和Month两个维度,确保统计粒度为「每个年份下的每个自然月」,计算得到的均值就是对应年-月组合下的平均儒略日 - 带空格的列名用反引号包裹,避免语法解析错误
- 在filter步骤补充需要的Subsite等筛选条件,匹配数据过滤需求
修正后代码
library(dplyr) library(ggplot2) Plot1 <- df %>% # 按需修改筛选条件,示例中补充了subsite筛选规则 filter(site == "A", subsite == "w", Year > 1985, species == "2") %>% # 核心修正:同时按年份、月份分组,匹配目标统计粒度 group_by(Year, Month) %>% # 带空格列名用反引号包裹,加na.rm处理缺失值 mutate(Day = mean(`julian day`, na.rm = TRUE)) %>% ungroup() %>% ggplot(aes(x = factor(Year), y = Day, fill = factor(Month))) + geom_boxplot() + stat_summary(fun = mean, geom = "point", shape = 1, size = 1, show.legend = FALSE) + stat_summary(fun = mean, colour = "red", geom = "text", show.legend = FALSE, vjust = -0.7, size = 3, aes(label = round(after_stat(y), digits = 0))) + # 可按需修改坐标轴标签 labs(x = "年份", y = "月平均儒略日", fill = "月份")
补充说明
- 如果需要同时对比多个站点、亚站点、物种的统计结果,不需要重复写筛选代码,直接在分组步骤加入对应维度,最后加
facet_wrap(~site + subsite + species)即可批量出分面图 - ggplot2 3.3.0及以上版本已经不推荐使用
..y..的写法,替换为after_stat(y)的兼容性更好 - 注意匹配数据框实际列名的大小写,示例数据列名为小写的
site/subsite/species,原代码中写大写的Site/Species会触发「找不到对象」报错,需要和实际数据的列名保持一致
内容的提问来源于stack exchange,提问作者RGR_288
相关产品推荐
相关产品推荐

