21

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

4

3 回答 3

16

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

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

于 2015-07-11T17:42:54.067 回答
8

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

compose(sum,abs,round,c)(1.5,-2.3,3.4)
于 2015-07-11T18:21:47.770 回答
7

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

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
)

与@BenBolker 的解决方案一样, backpipe也不受其他参数的限制。例如,这适用于backpipe

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

另请参阅讨论此问题的关于magrittr github 问题的讨论。

于 2015-09-03T17:04:35.443 回答