如何将变量传入ggplot aes的..y..部分?解决二元运算符报错
解决ggplot次坐标轴变量传入报错的问题
这个问题我之前也踩过坑,核心原因是ggplot的aes()函数会优先从你传入的数据框(这里是df)里查找变量,而你定义的transform是全局环境中的数值变量,aes(y = ..y.. * transform)里的transform会被ggplot当成df里的列名去查找——但你的数据框根本没有这列,自然就报出了「非数值参数」的错误。
下面给你三种可行的解决方法:
方法1:用准引用!!注入全局变量
这是最推荐的现代ggplot写法,用rlang包的!!(双感叹号)告诉ggplot:「别去数据框里找,就用我全局环境里的这个数值!」
library(ggplot2) a.samples <- rbeta(10000, 25, 75) b.samples <- rbeta(10000, 35, 65) df <- data.frame(x = b.samples/a.samples) p <- ggplot(df, aes(x = x)) + geom_histogram(fill = 'grey50', alpha = .6) transform <- max(ggplot_build(p)$data[[1]]$ymax) # 关键修改:给transform加上!! p + geom_line(aes(y = ..y.. * !!transform), stat='ecdf') + geom_vline(xintercept = 1, linetype = 'dashed') + scale_y_continuous(sec.axis = sec_axis(~./transform, name = "ecdf")) + guides(color = FALSE)
方法2:用get()从全局环境获取变量
如果你不习惯准引用的语法,也可以用get()函数明确指定从全局环境中读取transform变量:
p + geom_line(aes(y = ..y.. * get("transform", envir = globalenv())), stat='ecdf') + geom_vline(xintercept = 1, linetype = 'dashed') + scale_y_continuous(sec.axis = sec_axis(~./transform, name = "ecdf")) + guides(color = FALSE)
方法3:把变量加入数据框
既然aes()默认找数据框里的变量,那我们直接把transform添加到df里,这样ggplot就能直接找到它:
df$transform <- transform # 将全局变量加入数据框 p + geom_line(aes(y = ..y.. * transform), stat='ecdf') + geom_vline(xintercept = 1, linetype = 'dashed') + scale_y_continuous(sec.axis = sec_axis(~./transform, name = "ecdf")) + guides(color = FALSE)
这三种方法都能解决你的问题,其中方法1是ggplot官方推荐的现代语法,代码更简洁直观。
内容的提问来源于stack exchange,提问作者BigTimeStats
相关产品推荐
相关产品推荐

