6

我遇到过一种情况,%>%当与!. 考虑以下代码:

x <- c(1:20)
y <- !is.na(x)

> y
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 
     TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

> sum(Y)
[1] 20

好吧,这没什么好奇怪的。但是,如果我尝试使用%>%奇怪的东西来缩短它:

!is.na(x) %>% sum

[1] TRUE

TRUE?? 不是我所期望的——它应该是20

如果我删除它,它会按预期!给我:0

> is.na(x) %>% sum
[1] 0

如果我添加括号它可以工作:

> {!is.na(x)} %>% sum
[1] 20

并将!其视为功能有效:

> is.na(x) %>% `!` %>% sum
[1] 20

在做什么!is.na(x) %>% sum,为什么它返回TRUE而不是20

编辑:其他逻辑运算符产生类似的行为:

> T&T %>% sum()
[1] TRUE
> {T&T} %>% sum()
[1] 1

> T|T %>% sum()
[1] TRUE
> {T|T} %>% sum()
[1] 1
4

3 回答 3

6

我怀疑这是操作顺序问题:

!is.na(x) %>% sum

正在评估

!(is.na(x) %>% sum)

这相当于TRUE

于 2016-06-09T17:51:47.970 回答
4

尽管我接受了 @C-Z_ 的回答,但我想添加另一个来提供有关此内容的上下文。感谢@rawr 指导我?Syntax

基本上%>%被认为是一个操作符,就像%in%它必须遵守操作的顺序一样。在Syntax帮助页面上,这对应于%any%运算符(即任何中缀运算符),因为用户可以随意定义这些。碰巧,这意味着%>%在任何逻辑运算符之前以及算术运算符(例如*and \)之前触发。因此,如果你像我一样天真,认为左边的%>%会在链的下一步之前完成,你会得到一些惊喜。例如:

3+2 %>% '*'(4) %>% `/`(2)

不做3+2=5, 5*4= 20, 20/2=10

相反,它确实如此2*4/2=4, 4+3=7,因为%>% 优先于+

如果您使用magrittr包中的功能,例如:

add(3,2) %>% multiply_by(4) %>% divide_by(2) 

你得到10了预期的结果。在 周围放置括号3+2也会得到你10

在我最初的示例中,逻辑运算符!的优先级低于%>%,因此它们在总和竞争后最后执行。

故事的寓意:小心%>%与其他运营商混在一起。

于 2016-06-09T18:30:12.457 回答
1

您还可以使用 magrittr 包中的“not”别名:

> is.na(1:20) %>% not %>% sum

[1] 20

于 2016-06-16T08:48:07.247 回答