Search code examples
rwolfram-mathematicaassociativitymagrittr

Is right-to-left operator associativity in R possible?


I'm new to R, and I just discovered I suffer from Bracket Phobia (see comment in the link). I like the way magrittr notation %>% works, because it avoids nested parenthesis in some situations, and makes code more readable. I came from Mathematica, where there is a very similar native // notation to do what %>% does. Here are some R and Mathematica comparisons:

#R Notation    
c(1.5,-2.3,3.4) %>% round %>% abs %>% sum  

#Mathematica Notation
{1.5,-2.3,3.4}//Round//Abs//Total

So far so good, but, my question is:

Is there some way to mimic Mathematica @ notation, with right-to-left associativity in R?

Here is how it works in Mathematica, to solve the same code above:

Total@Abs@Round@{1.5,-2.3,3.4}

In Mathematica it can also be write as:

Total[Abs[Round[{1.5,-2.3,3.4}]]]

just like in R it would be:

sum(abs(round(c(1.5,-2.3,3.4))))

But it would be much more clean (and cool) to have in R something like this:

sum@abs@round@c(1.5,-2.3,3.4)

PS: I know @ is used in S4 classes, and is not a good idea. This is just an illustrative comparison.


Solution

  • The backpipe package was designed and created for this purpose. It provides a backpipe (right-to-left) operator for magrittr, pipeR and generally for any forward pipe operator. backpipe can be found on github and on CRAN.

    library(magrittr)  # or library(pipeR)
    library(backpipe)
    
    x <- c(1.5,-2.3,3.4)
    sum %<% abs %<% round %<% x
    
    all.equal(                             # TRUE
          x %>% round %>% abs %>% sum,
          sum %<% abs %<% round %<% x
    )
    

    backpipe also is not limited by additional parameters as is the case of the @BenBolker's solution. This, for example, works with backpipe :

    mean(na.rm=TRUE) %<% c(1:3,NA)  
    

    See also the discussion on the magrittr github issue that discuss this.