R 中从右到左的运算符关联性是否可能?

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

我是 R 的新手,我刚刚发现我患有 Bracket Phobia(请参阅 link 中的评论)。我喜欢 magrittr 符号 %>% 的工作方式,因为它在某些情况下避免了嵌套括号,并使代码更具可读性。我来自 Mathematica,那里有一个非常相似的原生 // 符号来做 %>% 所做的事情。以下是 R 和 Mathematica 的一些比较:

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

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

到目前为止一切顺利,但是,我的问题是:

有没有办法模仿 Mathematica @ notation,在 R 中具有从右到左的关联性?

下面是它在 Mathematica 中的工作原理,以解决上面相同的代码:

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

在Mathematica中也可以写成:

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

就像在 R 中一样:

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

但是在 R 中有这样的东西会更干净(也更酷):

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

PS:我知道 @ 在 S4 类 中使用,这不是一个好主意。这只是一个说明性的比较。

我根本没有 tested/thought 仔细考虑过这个问题,但是通过运算符定义函数组合(如下所示)似乎在几个测试用例中有效:

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)

语法不如能够为组合运算符使用单个字符(例如 @)那么好,但即使您可以找到一个未使用的字符(所有明显的字符 [!@#$%^&*~|] 被采用,屏蔽它们将是一个糟糕的主意)有一个解析器限制:R 中用户定义的二元运算符必须采用 %?%.

形式

使用 hadley 的 purrr 包中的 compose 怎么样?

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

backpipe 包就是为此目的而设计和创建的。它为 magrittrpipeR 提供了一个后管(从右到左)运算符,并且通常为任何前向管道运算符。 backpipe 可以在 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 也不受其他参数的限制,就像@BenBolker 的解决方案一样。例如,这适用于 backpipe :

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

另请参阅讨论此问题的 magrittr github issue 上的讨论。