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

时间:2015-07-08 23:04:47

标签: r wolfram-mathematica associativity magrittr

我是R的新手,我刚刚发现我患有Bracket Phobia(请参阅链接中的评论)。我喜欢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课程,并不是一个好主意。这只是一个说明性的比较。

3 个答案:

答案 0 :(得分:15)

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

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中用户定义的二元运算符必须是%?%形式。

答案 1 :(得分:7)

如何使用hadley的compose包中的purrr

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

答案 2 :(得分:6)

backpipe 包是为此目的而设计和创建的。它为 magrittr pipeR 提供了一个反向管(从右到左)运算符,通常用于任何正向管道运算符。可以在githubCRAN上找到 backpipe

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的讨论。