R中dplyr group_by结合ggplot2按分组设置动态绘图标题
问题原因
你代码所有图标题相同的核心原因是labs()中调用的df_summarised$year、df_summarised$Isotope都是原全量数据框的列,会默认取全量数据的第一个值作为所有图的标题内容。在group_by+do的逻辑中,代表当前分组子集的变量是.,你只需要从当前分组子集中取值即可。
修正方案
方案1:直接修改你原有的do写法
只需要把标题里的取值对象从原数据框改为当前分组子集,取分组内唯一的第一个同位素/年份值即可:
ActivityPlots <- df_summarised %>% group_by(Isotope,year) %>% do( plots = ggplot(data=., aes(x=month,y=TotalMonthlyExcretion)) + geom_bar(stat="identity", width = .5, fill="tomato3") + labs(title = paste("Liquid Radioactive Waste. Year: ", .$year[1]," Isotope: ", .$Isotope[1]), x = "Month", y = "Total Monthly Excretion (MBq)", caption = paste("Year: ",.$year[1]) ) + theme_bw() + theme( plot.title = element_text(color="black", size=14, face="bold.italic"), axis.title.x = element_text(size=14, face="bold"), axis.title.y = element_text(size=14, face="bold")) )
方案2:更推荐的现代tidyverse写法(含自动保存png逻辑)
do()函数已经属于tidyverse中淘汰的语法,更推荐用nest() + purrr::map的组合实现分组绘图,还可以直接在代码中完成单独png文件的保存,不需要额外写循环:
library(tidyverse) # 先分组嵌套,再批量绘图+保存 ActivityPlots <- df_summarised %>% group_by(Isotope, year) %>% nest() %>% mutate( # 绘图 plots = pmap(list(data, Isotope, year), function(df, iso, y) { ggplot(data=df, aes(x=month,y=TotalMonthlyExcretion)) + geom_bar(stat="identity", width = .5, fill="tomato3") + labs(title = paste0("Liquid Radioactive Waste. Year: ", y," Isotope: ", iso), x = "Month", y = "Total Monthly Excretion (MBq)", caption = paste("Year: ", y) ) + theme_bw() + theme( plot.title = element_text(color="black", size=14, face="bold.italic"), axis.title.x = element_text(size=14, face="bold"), axis.title.y = element_text(size=14, face="bold") ) }), # 自动保存为png,文件名包含同位素和年份,不会重名 save_path = pmap(list(plots, Isotope, year), function(p, iso, y) { ggsave(filename = paste0("放射性废液排放_", y, "_", iso, ".png"), plot = p, width = 8, height = 6, dpi = 300) }) )
运行上述代码后,会直接在你的工作目录下生成每个同位素+年份组合的独立png文件,文件名自带分组标识方便查找。
内容的提问来源于stack exchange,提问作者moadeep
相关产品推荐
相关产品推荐

