我是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课程,并不是一个好主意。这只是一个说明性的比较。
答案 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 提供了一个反向管(从右到左)运算符,通常用于任何正向管道运算符。可以在github和CRAN上找到 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的讨论。