ggplot2用stat_summary_2d替换geom_tile绘图报错如何解决
报错原因
报错本质是变量作用域问题:
- 你在最外层绘图管道第一步用
mutate创建的cancel列,仅存在于管道流转的临时数据集中,没有覆盖或保存到全局环境的原始flights对象里。 - 后续
geom_text的data参数直接调用了原始flights数据集做分组汇总,这个原始数据里不存在cancel列,执行mean(cancel)时自然会触发对象找不到的计算错误。
除此之外你写的stat_summary_2d版本还有3个逻辑偏差,即使修复报错也无法得到和原图一致的结果:
stat_summary_2d默认聚合函数是计算z值的均值,输出为0-1区间的取消比例,没有转换为你需要的百分比数值,填充色映射尺度和原图不一致- x、y轴映射顺序写反,原图x轴为
origin、y轴为carrier,你的代码里映射顺序颠倒,输出图表轴结构不对 stat_summary_2d默认是对连续坐标做分箱,直接传入离散的字符型坐标会触发自动分箱,可能把多个类别合并到同一个格子,无法得到和geom_tile一样的每个分组对应一个格子的效果
修复代码
不需要重复写分组汇总逻辑,直接让stat_summary_2d完成百分比计算,文本标注复用统计计算结果即可,代码更简洁也不会出现变量找不到的问题:
library(nycflights13) library(tidyverse) # 提前生成带取消标记的数据集,避免临时变量作用域问题 flights_cancel <- flights %>% mutate(cancel = as.integer(is.na(dep_time))) flights_cancel %>% ggplot(aes(x = origin, y = carrier, z = cancel)) + # 自定义聚合函数,直接计算百分比取消率,指定分箱数匹配离散类别数量 stat_summary_2d( fun = ~ 100 * mean(.x, na.rm = TRUE), bins = c(n_distinct(flights$origin), n_distinct(flights$carrier)) ) + # 复用stat_summary_2d的聚合逻辑,直接调用计算好的数值做文本标注 geom_text( stat = "summary_2d", fun = ~ 100 * mean(.x, na.rm = TRUE), aes(label = round(after_stat(value), 1)), color = "blue", size = 5 ) + scale_fill_distiller("Cancel Ratio", palette = "RdYlGn") + theme_bw()
修复说明
- 提前生成带取消标记的数据集,从根源上避免内层数据调用找不到临时变量的问题
- 给
stat_summary_2d传入自定义聚合函数,直接输出百分比格式的取消率,和原图填充映射逻辑完全对齐 - 显式指定
bins参数,分箱数和x、y轴的离散类别数量完全一致,保证每个carrier+origin组合对应一个独立瓷砖,和geom_tile效果一致 - 文本标注同样使用
stat_summary_2d的统计规则,通过after_stat(value)直接读取计算好的取消率,不需要单独写分组汇总代码,减少重复计算和出错概率 - 修正x、y轴映射顺序,输出图表结构和原
geom_tile版本完全一致
内容的提问来源于stack exchange,提问作者Keith Duong
相关产品推荐
相关产品推荐

