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

↘锁芯ラ 提交于 2019-12-03 16:16:33

问题


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.


回答1:


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.




回答2:


I haven't tested/thought about this carefully at all, but defining function composition via an operator (as below) seems to work in a couple of test cases:

library(magrittr)

## operator defined as  "left-pointing arrow" at the 
##    suggestion of @ClausWilke:
"%<%" <- function(x,y) { if (is(y,"function")) 
          function(z) x(y(z)) 
      else x(y) }

x <- c(1.5,-2.3,3.4)
all.equal(x %>% round %>% abs %>% sum,
          sum %<% abs %<% round %<% x)

x <- rnorm(1000)
all.equal(x %>% round %>% abs %>% sum,
          sum %<% abs %<% round %<% x)

The syntax is not as nice as being able to use a single character (such as @) for the composition operator, but even if you could find an unused one (all the obvious ones [!@#$%^&*~|] are taken, and masking them would be a terrible idea) there's a parser limitation: user-defined binary operators in R must be of the form %?%.




回答3:


How about using compose from hadley's purrr package?

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


来源:https://stackoverflow.com/questions/31305342/is-right-to-left-operator-associativity-in-r-possible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!