5

1 Lets look at this example:

1:3 %>% rep(.,2) + 1 %>% sum  #[1] 2 3 4 2 3 4

[2] What R is doing is:

1:3 %>% rep(.,2) + (1 %>% sum)

[3] What I want R to do is: (which gives an error) , I like to get 18 there.

1:3 %>% (rep(.,2) + 1) %>% sum  #Error in rep(., 2) : attempt to replicate an object of type 'closure'

[4] So I need to go super lame:

tmp <- 1:3 %>% rep(.,2) + 1
tmp %>% sum #[1] 18

How can I fix [3] to work. Can someone explain me the error message?

Edit

From here

Note that the variable x on the left side of %>% is applied as the first argument in the function on the right side. This default behaviour can be changed using . which is called a placeholder.

However, one important thing to remember is, when the . appears in nested expressions, the first-argument-rule is still applied. But this behaviour can be suppressed using the curly braces{ }

Interestingly, what I didn't know:

This is the equal:

1:3 %>% sum(rep(.,3))   #[1] 24
1:3 %>% sum(.,rep(.,3)) #[1] 24

And these two are equal:

1:3 %>% {sum(rep(.,3))}  #[1] 18
1:3 %>% rep(.,3) %>% sum #[1] 18 

Edit2

> packageVersion("magrittr")
[1] ‘1.5’

This:

?'%>%'

gives: (I don't know what package is behind my %>% operator, I don't like that too much to be honest)

Help on topic '%>%' was found in the following packages:

Pipe operator (in package tidyr in library C:/Program Files/R/R-3.3.2/library) magrittr forward-pipe operator (in package magrittr in library C:/Program Files/R/R-3.3.2/library) Pipe operator (in package stringr in library C:/Program Files/R/R-3.3.2/library) Objects exported from other packages (in package dplyr in library C:/Program Files/R/R-3.3.2/library)

Andre Elrico
  • 10,956
  • 6
  • 50
  • 69
  • 7
    `1:3 %>% {rep(.,2) + 1} %>% sum` – talat Feb 13 '18 at 14:29
  • Thank you sir! Can you elaborate on the error msg too? – Andre Elrico Feb 13 '18 at 14:31
  • No, sorry, but I'm not good at explaining that stuff. – talat Feb 13 '18 at 14:41
  • 1
    What version of `magrittr` are you using? When I run [3] i get the error "Error in eval(rhs, env, env) : object '.' not found". Tested with `magrittr_1.5`. – MrFlick Feb 13 '18 at 14:42
  • @MrFlick look at Edit2 – Andre Elrico Feb 13 '18 at 14:56
  • Does `exists(".")` return TRUE or FALSE? It should return FALSE. Otherwise you may have assigned something to `.` or another package might define `.` to be something other than just a place holder which gives you the different error message. And I'm not sure these "edits" are helpful. If you are trying to answer your own question, you should add that below. You should just ask one clear question. No need to label "edit"s; we can see that from the question history. – MrFlick Feb 13 '18 at 14:59
  • exists(".") evals TRUE and is from plyr. – Andre Elrico Feb 13 '18 at 15:05
  • 1
    Then you probably get that same error if you just do `rep(.,2)`. Which is the basically the same as `f<-function() {1}; rep(f, 2)`. You are trying to pass a function to `rep()` which is what the error message means. And this is because the parenthesis are trying to evaluate the the stuff inside before running the chain. You'd get the same error as me if you didn't have `plyr` loaded. – MrFlick Feb 13 '18 at 15:16
  • Yes, that's right! – Andre Elrico Feb 13 '18 at 15:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165071/discussion-between-andre-elrico-and-mrflick). – Andre Elrico Feb 13 '18 at 16:32

1 Answers1

3

The binary operator + is creating the problem. It has lower precedence than the pipe (see ?Syntax). Either enclose the entire operation in parentheses before piping to sum, or use the functional form of +:

(1:3 %>% rep(.,2) + 1) %>% sum
[1] 18

1:3 %>% rep(.,2) %>% `+`(1) %>% sum
[1] 18
James
  • 65,548
  • 14
  • 155
  • 193