我正在尝试更新一些旧的绘图代码,这些代码给出了以下消息:
Warning message: `aes_string()` was deprecated in ggplot2 3.0.0. Please use tidy evaluation ideoms with `aes()`
当我用 aes() 替换 aes_string() 并取消引用 !! 时,我开始在意想不到的地方收到消息“错误:提供给连续比例的离散值”。
这是一个简化的可重现示例:
# Make some test data
set.seed(1)
dat <- data.frame(x=rnorm(100),y=rnorm(100),value=rnorm(100))
xvar <- 'x'
yvar <- 'y'
cvar <- 'value'
# This works, but gives a deprecated warning for use of aes_string()
ggplot(dat,aes_string(x=xvar,y=yvar,color=cvar)) + geom_point() + scale_color_gradientn(colors = rainbow(10))
# This changes the plot to use aes() with !! instead of using aes_string()
# It fails with "Error: Discrete value supplied to continuous scale"
ggplot(dat,aes(x=!!xvar,y=!!yvar,color=!!cvar)) + geom_point() + scale_color_gradientn(colors = rainbow(10))
我无法弄清楚导致此问题的原因,但看起来映射本身在 ggplot 中的处理方式不同 - 使用 aes_string() 变量名称以 ~ 开头显示,并且与 aes() 和 !!他们不:
# Capture each plot so it can be examined
plt_working <- ggplot(dat,aes_string(x=xvar,y=yvar,color=cvar)) + geom_point() + scale_color_gradientn(colors = rainbow(10))
plt_broken <- ggplot(dat,aes(x=!!xvar,y=!!yvar,color=!!cvar)) + geom_point() + scale_color_gradientn(colors = rainbow(10))
summary(plt_working) # The second line says "mapping: colour = ~value, x = ~x, y = ~y"
summary(plt_broken) # The second line says "mapping: x = x, y = y, colour = value" (no ~s)
~是什么意思?在这种情况下,它似乎与公式或方面没有任何关系。
为什么此更改会使绘图代码停止工作,更新代码以使其仍然有效的正确方法是什么?
最佳答案
当前(截至 2023 年)在 aes()
内部使用字符串的首选方法是通过 ggplot 的 .data
对象(感谢 Lionel Henry 澄清了推理)后面):
xvar <- 'x'
yvar <- 'y'
cvar <- 'value'
ggplot(dat,aes(x = .data[[xvar]], y = .data[[yvar]], color = .data[[cvar]])) + geom_point() + scale_color_gradientn(colors = rainbow(10))
或者,您可以将字符串包装在 sym()
中,然后使用 !!
将它们解开在 aes()
中:
set.seed(1)
dat <- data.frame(x=rnorm(100),y=rnorm(100),value=rnorm(100))
xvar <- sym('x')
yvar <- sym('y')
cvar <- sym('value')
ggplot(dat,aes(x=!!xvar,y=!!yvar,color=!!cvar)) + geom_point() + scale_color_gradientn(colors = rainbow(10))
关于r - 使用整洁的评估和 aes() 而不是 aes_string() 时 ggplot2 映射发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75217038/