ggplot2中的"+"运算符与magrittr中的"%>%"运算符有什么区别?

15

ggplot2中的"+"运算符和magrittr中的"%>%"运算符有什么区别?

我被告知它们是相同的,但是如果我们考虑以下脚本。

library(magrittr)
library(ggplot2)

# 1. This works
ggplot(data = mtcars, aes(x=wt, y = mpg)) + geom_point()

# 2. This works
ggplot(data = mtcars) + aes(x=wt, y = mpg) + geom_point()

# 3. This works
ggplot(data = mtcars) + aes(x=wt, y = mpg) %>% geom_point()

# 4. But this doesn't
ggplot(data = mtcars) %>% aes(x=wt, y = mpg) %>% geom_point()

2
此外,顺带一提,您不需要所有这些导入。在您的示例中包含它们会使排除交叉库干扰变得困难。 - Matthew Drury
3
我已经编辑了你的问题,使用内置数据代替你自己的数据,消除了未使用的包,并使整个问题可以复制粘贴。 - Gregor Thomas
1个回答

19

管道操作和ggplot2的加法非常不同。管道操作符%>% 的作用是将左侧的结果作为右侧函数的第一个参数。例如:

1:10 %>% mean()
# [1] 5.5

等价于 mean(1:10)。管道符更适用于替代嵌套的函数,例如,

x = factor(2008:2012)
x_num = as.numeric(as.character(x))
# could be rewritten to read from left-to-right as
x_num = x %>% as.character() %>% as.numeric()

但这在 《R语言中的%>%是什么意思?》 中都讲得很清楚,你可以阅读一下那里获取更多例子。

有了这个知识,我们可以将你的管道示例重写为嵌套函数,并且看到它们仍然执行相同的操作。但现在(希望)显而易见的原因是为什么#4不起作用:

# 3. This is acceptable ggplot2 syntax
ggplot(data = mtcars) + geom_point(aes(x=wt, y = mpg))

# 4. This is not
geom_point(aes(ggplot(data = mtcars), x=wt, y = mpg))

ggplot2 包含一个特殊的 "+" 方法,用于向绘图添加层。在您问出这个问题之前,我不知道它也可以与 aes() 函数一起使用,但显然也定义了这个功能。所有这些都是在 ggplot2 中特别定义的。在 ggplot2 中使用 + 的方式先于管道符号,虽然使用方式相似,但功能却大不相同。

有趣的是,ggplot2 的创建者 Hadley Wickham 曾说过

......如果我早些时候发现了管道符号,就不会有 ggplot2 这个作品了,因为你可以将 ggplot 图形写成...

ggplot(mtcars, aes(wt, mpg)) %>%
  geom_point() %>%
  geom_smooth()

3
在我匆忙的评论中,我简单地忽视了 %>% 运算符比 + 运算符优先级高的事实。毕竟这也不足为奇。 - baptiste
是的,他们的评论已经消失了。我现在正在清理一些东西。 - Gregor Thomas
1
哇,Hadley Wickham的那句话真是太棒了。它帮助我解释了很多困惑。难怪ggplot2如此令人困惑。它试图重新发明管道!加号运算符现在变得非常清晰:它是ggplot2特有的,我应该停止试图理解它。这只是ggplot2添加层的方式,没有更多的含义。 - Tom Rose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接