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 包就是为此目的而设计和创建的。它为 magrittr、pipeR 提供了一个后管(从右到左)运算符,并且通常为任何前向管道运算符。 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 上的讨论。
我是 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 包就是为此目的而设计和创建的。它为 magrittr、pipeR 提供了一个后管(从右到左)运算符,并且通常为任何前向管道运算符。 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 上的讨论。