Use of ! (or any logical operator) with %>% (magrittr) produces unexpected output

前端 未结 3 1913
猫巷女王i
猫巷女王i 2021-01-18 14:28

I have run across a situation where %>% produces very surprising output when combined with !. Consider the following code:

x <         


        
相关标签:
3条回答
  • 2021-01-18 14:30

    I suspect that it's an order of operations issue:

    !is.na(x) %>% sum
    

    is evaluating to

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

    Which is equivalent to TRUE

    0 讨论(0)
  • 2021-01-18 14:47

    You can also use the "not" alias from the magrittr package:

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

    [1] 20

    0 讨论(0)
  • 2021-01-18 14:50

    Although I accepted @C-Z_ 's answer I want to add another to provide context on this. Thanks to @rawr for directing me to ?Syntax.

    Basically %>% is considered to be an operator, like %in% and as such it has to obey the order of operations. On the Syntax help page this corresponds to the %any% operator (i.e. any infix operator), as users can define these at will. As it happens, this means that %>% fires before any logical operator and also before arithmetic operators (e.g. * and \). As a result, if you are naively, like I was, thinking that the left side of %>% will complete before the next step in the chain, you can get some surprises. For example:

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

    Does not do 3+2=5, 5*4= 20, 20/2=10

    instead it does 2*4/2=4, 4+3=7, because the %>% has precedence over +.

    If you use the functions in the magrittr package such as:

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

    You get 10 as expected. Placing brackets around the 3+2 will also get you 10.

    In my original examples, the logical operators, such as ! have a lower precedence than %>%, so they act last, after the sum has competed.

    Moral of the story: Be careful mixing %>% with other operators.

    0 讨论(0)
提交回复
热议问题