r语言 - 使用 !(或任何逻辑运算符)与 %>% (Magrittr) 产生意外的输出



我遇到过这样一种情况:%>%!组合时会产生非常惊人的输出。考虑以下代码:

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

将CCD_ 8作为一个函数处理:

> 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

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

!is.na(x) %>% sum

正在评估

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

相当于TRUE

虽然我接受了@C-Z_的答案,但我想添加另一个来提供上下文。感谢@rawr指导我访问?Syntax

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

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

在我最初的例子中,逻辑运算符(如!)的优先级低于%>%,因此它们在和竞争之后最后起作用。

故事寓意:小心将%>%与其他运算符混合。

您也可以使用magrittr包中的"not"别名:

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

[1] 20

相关内容

  • 没有找到相关文章

最新更新