ggplot2美学映射中如何使用统计计算结果与数据集变量做即时运算
报错原因
stat_density()等统计变换层的计算环境默认仅包含该层统计输出的结果变量(可通过after_stat()/旧版stat()调用),原始数据集的其他变量不会直接传入该环境。同时统计变换输出的结果长度通常和原始观测数不一致(比如密度估计输出的是拟合分位点的结果,和原始数据行数不等),直接调用原始变量必然会提示找不到对象。
额外说明:如果你使用的是
stat_identity()这类不改变输入数据长度的统计变换层,原始变量可以直接在美学映射中调用,不需要额外处理。
实现方案
方案1:使用stage()分阶段映射(ggplot2 3.3.0+ 支持,推荐)
stage()函数支持在美学映射的三个阶段(初始映射、统计变换后、位置调整后)分别定义计算逻辑,你可以通过初始映射传入需要用到的原始变量,再在统计变换完成后结合计算结果做运算:
注:你示例中的
stat(density) * pop本身统计逻辑不成立,二者长度不匹配无法按元素相乘,以下为合理的按组调整密度的示例:
library(ggplot2) # 示例:按气缸数分组,每组密度值乘以该组的平均重量 ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) + stat_density( aes(y = stage( start = wt, # 初始映射传入原始wt变量 after_stat = density * tapply(start, group, mean)[as.character(group)] )) )
方案2:提前手动完成统计计算
如果对ggplot2的映射逻辑不熟悉,更稳妥的方式是提前手动计算需要的统计量,再合并需要用到的原始变量后绘图,逻辑更透明:
library(ggplot2) library(dplyr) # 手动计算pce的密度估计结果 density_df <- as.data.frame(density(economics$pce)) # 提前计算需要用到的原始变量统计量,比如pop的均值 density_df$pop_mean <- mean(economics$pop) # 直接用计算好的数据绘图 ggplot(density_df, aes(x = x, y = y * pop_mean)) + geom_line() + labs(x = "pce", y = "density * pop_mean")
内容的提问来源于stack exchange,提问作者Martin C. Arnold
相关产品推荐
相关产品推荐

