40

I would like to understand why, in the the dplyr or magrittr package, and more specifically the chaining function %>% has some trouble with the basic operators +, -, *, and /

Chaining takes the output of previous statement and feeds it as first argument of the next:

1:10 %>% sum
# [55]

Thus how come this doesn't work

1:10 %>%  *2 %>% sum
1:10 %>% .*2 %>% sum

I also found that the following syntax works for adding/substracting, but not multiply or divide. why so?

1:10 %>% +(2) # works OK
1:10 %>% *(2) # nope...

So should I write an anonymous function even to do a *2 operation on my data.frame?

1:10 %>% (function(x) x*2) %>% sum

Thanks, I couldn't find the answer in other SO questions.

agenis
  • 7,337
  • 5
  • 44
  • 92
  • 6
    You want to use the `magrittr` package here instead of dplyr. dplyr is only for working with data.frames while the pipe operator (`%>%`) is originally from magrittr. – talat Dec 08 '14 at 18:26
  • 2
    Just add them normally? – stanekam Jan 23 '15 at 02:31
  • 4
    Explanation of this behaviour: plus and minus only work here because the parser sees them as unary plus and minus operators, as in `-2`. So its valid syntax. So it parses okay here, and then magrittr gets to work mangling the evaluation into a binary `"-"(x, 2)` expression. There's no unary '*' or '/' function, so those ops fail. Once quoted, they become valid syntax again and the corresponding function is gotten. – Spacedman Jan 23 '15 at 14:27
  • Eventually I add that this way of doing also works for test operators such as '>', '=='. – agenis Mar 07 '16 at 22:54

3 Answers3

58

Surround the operators with backticks or quotes, and things should work as expected:

1:10 %>%  `*`(2) %>% sum
# [1] 110

1:10 %>%  `/`(2) %>% sum
# [1] 27.5
jbaums
  • 26,405
  • 5
  • 76
  • 118
  • 11
    Better to use backticks to quote, because it more clearly distinguishes between non-syntactic function names and strings. (The fact that `"+"(1, 3)` works is, in my opinion, a historical artefact. – hadley Dec 08 '14 at 22:11
45

Or use the Aliases in magrittr package, e.g.:

1:10 %>% multiply_by(2)
# [1]  2  4  6  8 10 12 14 16 18 20

1:10 %>% add(2)
# [1]  3  4  5  6  7  8  9 10 11 12

The Aliases include 'words' for boolean operators, extract/replace, and arithmetic operators

Henrik
  • 61,039
  • 13
  • 131
  • 152
0

As an addition to the answer above, it is handy to use Aliases in magrittr package, e.g.:

magrittr's pipeable operator replacements

operator functional alternative
x * y x %>% multiply_by(y)
x ^ y x %>% raise_to_power(y)
x[y] x %>% extract(y)
Phoenix
  • 1,871
  • 1
  • 4
  • 22