请参见下面的代码行; 谋杀是一个包含变量/列总数,人口和比率的数据框:
r <- murders %>% summarize (rate = sum(total) / sum(population) * 10^6) %>% .$rate
在这种情况下,操作员%>%.$
的工作情况如何?有人可以详细说明吗?
编辑:我知道这行代码的结果(它提取了 rate 列),但是想知道为什么会发生或如何发生,因为通常遵循%>%
通过一个函数,即使我们将$
运算符视为一个函数,它也不会在%>%
之后立即启动,而是在两者之间存在.
。如果我们说.
是%>%
函数中$
输出的占位符,那么%>%$
也应该起作用,因为%>%
的输出,默认情况下自动自动进入RHS函数的第一个参数(在我们的示例中为$
),在这种情况下不需要.
。
答案 0 :(得分:1)
pull
最开始的一个实际工作示例非常好。我建议在以后的问题中至少提供那么多。
library(dplyr)
murders <- data.frame('loc'=c('A','B','C'),
'population'=c(10,20,30),
'total'=c(2,3,5))
result <- murders %>%
summarize (rate = sum(total) / sum(population) * 10^6) %>%
.$rate
result # 166666.7
上面示例中的.
是result of the previous pipe。美元符号是提取运算符,它将返回名为rate的列。
pull
函数正在将管道的结果传递到第一个arg中。在这种情况下,由于pull的作用与提取($
)相同,因此发生的事情更加明确。
result_2 <- murders %>%
summarize (rate = sum(total) / sum(population) * 10^6) %>%
pull(rate)
result_2 # 166666.7
您可以通过以下操作说明这一点
result_3 <- murders %>%
summarize (rate = sum(total) / sum(population) * 10^6) %>%
pull(.data=., var=rate)
result_3 # 166666.7
$
或[[
无效短故事,$
和[[
是基元,magrittr %>%
works with functions。
将对象转发到函数或调用表达式中。
lhs%>%rhs
参数lhs
一个值或magrittr占位符。 rhs
使用magrittr语义的函数调用。
`$` # .Primitive("$")
`[[` # .Primative{"[[")
近似函数pull
或getElement
是函数
`getElement`
# function (object, name)
# {
# if (isS4(object))
# methods::slot(object, name)
# else object[[name, exact = TRUE]]
# }
# <bytecode: 0x5618b3018358>
# <environment: namespace:base>
答案 1 :(得分:1)
将foo$bar
表示法解析为等效于`$`(foo, bar)
,其中$
是一个函数。
此函数是原始函数这一事实与此处的作用完全无关。
以这个例子为例:
df <- data.frame(a=1:2, b = 3:4)
df
#> a b
#> 1 1 3
#> 2 2 4
由于运算符$
的优先级高于%>%
的优先级(请参见?Syntax
),因此以下等价:
df %>% .$a
#> [1] 1 2
df %>% (.$a)
#> [1] 1 2
df %>% `$`(., a)
#> [1] 1 2
实际上, magrittr 甚至无法“看到”前者和后者之间的区别。
然后由于magrittr的语义以及$
的R语法,以下是等效的:
df %>% `$`(., a)
#> [1] 1 2
`$`(df, a)
#> [1] 1 2
df$a
#> [1] 1 2
评论者对df %>% $a
不起作用感到惊讶,原因是 magrittr 无法操作任何魔术,如果语法不正确,则解析器将在调用任何函数之前阻塞!
这使我们为最后一部分做好了准备,因为df %>% +1
是正确的语法,所以 magrittr 会做什么?
如果我们回到?syntax
,我们会发现我们还有其他优先于%>%
的二进制运算符:::
,:::
,@
,{ {1}},[
和[[
。
我们无法对:
和::
(默认定义)使用相同的技巧,因为它们使用正则表达式,因此 magrittr 不会向它们提供适当的第一个参数,但是我们可以和其他参数一起玩:
:::
3 %>% .:5
#> [1] 3 4 5
df %>% .["a"]
#> a
#> 1 1
#> 2 2
和+
的特例 -
和+
符号具有特殊性,以一元(-
)或二进制(+1
)形式使用时,它们具有不同的优先级,并且一元形式的优先级高于1+2
。
由于解析器允许一元形式,%>%
是正确的语法,等效于df %>% +1
,因此magrittr然后像在任何函数上一样在df %>% `+`(1)
上应用其魔力,并添加了一个隐式点占位符作为第一个参数,因此以下调用是等效的:
+
如果要在 ggplot2 中使用管道,可以使用此古怪的属性:
df %>% +1 # unary '+'
df %>% `+`(1) # unary '+'
df %>% `+(.,1)` # binary '+' !!!
`+`(df,1) # binary '+' !!!
df + 1 # binary '+' !!!
后一个调用可以直接通过管道传递到另一个函数中,例如library(ggplot2)
cars %>%
ggplot(aes(speed, dist)) +
geom_point()
# equivalent
cars %>%
ggplot(aes(speed, dist)) %>%
+geom_point()
或saveRDS()
,而前一个则不能。