15

package "dplyr" has a chain operator. But I have a problem with how to get the right side term itself.

For example:

c(5,7,8,1) %>% sum(`[`(1:3)) # get result 27 (This is wrong)

c(5,7,8,1) %>% sum(.[1:3]) # get result 41 (This is also wrong)

c(5,7,8,1) %>% `[`(1:3) %>% sum()   # get result 20 (This is right)

Why the first line and second line codes are wrong? What has happened in them?

xirururu
  • 5,028
  • 9
  • 35
  • 64
  • 1
    I think in the second case , we are summing the `c(5,7,8,1) %>% c(.[1:3])` – akrun Oct 30 '15 at 10:42
  • @akrun `c(5,7,8,1) %>% c(.[1:3])` will give `5 7 8 1 5 7 8`, but c(5,7,8,1) %>% .[1:3] will give `5 7 8 1`. Why this happen? – xirururu Oct 30 '15 at 10:47
  • 1
    Because `%>%`give the lhs as the first parameter to the function, the extracted part is given as second – Tensibai Oct 30 '15 at 10:50
  • @akrun c(5,7,8,1) %>% c(`[`(1:3)) will give `5 7 8 1 1 2 3` back, but `c(5,7,8,1) %>% `[`(1:3)` give back `5 7 8`. I have no idea...Why this happens – xirururu Oct 30 '15 at 10:51

2 Answers2

16

The dot . is correct. However, %>% also inserts it as the first argument:

x = c(5,7,8,1)
x %>% sum(.[1 : 3])

Is the same as:

sum(x, x[1 : 3])

You can explicitly prevent this behaviour by wrapping the expression in braces:

x %>% {sum(.[1 : 3])}

However, at this point it may be better to split the pipeline up a bit more (as you’ve done yourself):

x %>% `[`(1 : 3) %>% sum()

Or, using magrittr helper functions (requires library(magrittr)):

x %>% extract(1 : 3) %>% sum()
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
5

Let's quote the doc:

Placing lhs as the first argument in rhs call The default behavior of %>% when multiple arguments are required in the rhs call, is to place lhs as the first argument, i.e. x %>% f(y) is equivalent to f(x, y).

So what happens ?

When you call sum, it is called like this:

n <- c(5,7,8,1) 
sum(n,n[1:3])

The lhs of %>% is passed as first arg to sum, and the subset as second arg. On your third form, only the ouput of the selector is passed as argument to sum

Tensibai
  • 15,557
  • 1
  • 37
  • 57