R中从右到左的运算符关联性是不是可能?
Posted
技术标签:
【中文标题】R中从右到左的运算符关联性是不是可能?【英文标题】:Is right-to-left operator associativity in R possible?R中从右到左的运算符关联性是否可能? 【发布时间】:2015-09-27 02:40:52 【问题描述】:我是 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 课程,这不是一个好主意。这只是一个说明性的比较。
【问题讨论】:
你应该看看 proto 包。 在 R 中做这样的事情,你需要一个具有从右到左关联性的运算符,而且似乎无法定义这样的运算符。 @MrFlick 感谢您的评论。我更改了帖子主题以使其更清晰。 这个话题也在magrittr
issue #26中讨论过:github.com/smbache/magrittr/issues/26
关于符号创建:question 32305096
【参考方案1】:
我根本没有仔细测试/考虑过这一点,但通过运算符定义函数组合(如下所示)似乎适用于几个测试用例:
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 中用户定义的二元运算符必须采用 %?%
的形式。
【讨论】:
这很有趣。很遗憾需要用%
包装,但我相信这是用户在R 中可以做到的最好的。我会等到赏金结束再选择你的答案,只是为了刺激其他人。 +1
只是为了好奇。你知道是否有可能改变解析器的行为?比如,测试类似: sum>>abs>>round>>c(1.5,-2.3,3.4) ?
并非没有extreme对R源代码的低级黑客攻击......例如您必须在低级 C 代码中找到解析代码并进行适当的修改。
有什么理由不将操作符定义为%<%
,表示数据是从右向左发送的?
@ClausWilke 我认为这是一个不错的建议。【参考方案2】:
使用 hadley 的 purrr
包中的 compose
怎么样?
compose(sum,abs,round,c)(1.5,-2.3,3.4)
【讨论】:
【参考方案3】:backpipe 包就是为此目的而设计和创建的。它为 magrittr、pipeR 和通常为任何正向管道运算符提供了一个背管(从右到左)运算符。 backpipe 可以在 github 和 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中从右到左的运算符关联性是不是可能?的主要内容,如果未能解决你的问题,请参考以下文章