Chain arithmetic operators in dplyr with %>% pipe
Asked Answered
A

4

49

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.

Acanthus answered 8/12, 2014 at 18:23 Comment(4)
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.Hanschen
Just add them normally?Pathy
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.Coleville
Eventually I add that this way of doing also works for test operators such as '>', '=='.Acanthus
A
66

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
Antecede answered 8/12, 2014 at 18:28 Comment(1)
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.Servais
P
50

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

Pangolin answered 8/12, 2014 at 18:35 Comment(0)
R
3

Thought I'd share the magrittr documentation so you could see all of your options!

Currently implemented aliases are...

extract `[`
extract2    `[[`
inset   `[<-`
inset2  `[[<-`
use_series  `$`
add `+`
subtract    `-`
multiply_by `*`
raise_to_power  `^`
multiply_by_matrix  `%*%`
divide_by   `/`
divide_by_int   `%/%`
mod `%%`
is_in   `%in%`
and `&`
or  `|`
equals  `==`
is_greater_than `>`
is_weakly_greater_than  `>=`
is_less_than    `<`
is_weakly_less_than `<=`
not (`n'est pas`)   `!`
set_colnames    `colnames<-`
set_rownames    `rownames<-`
set_names   `names<-`
set_class   `class<-`
set_attributes  `attributes<-`
set_attr    `attr<-`
Revetment answered 26/11, 2022 at 18:43 Comment(0)
D
1

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)
Degrade answered 22/12, 2021 at 22:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.