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)

语法不如组合运算符能够使用单个字符(例如@)好,但即使您可以找到一个未使用的字符(所有明显的[!@#$%^&amp;*~|] 都被占用,并且屏蔽它们将是一个糟糕的主意)存在解析器限制:R 中用户定义的二元运算符必须采用 %?% 的形式。

【讨论】:

这很有趣。很遗憾需要用% 包装,但我相信这是用户在R 中可以做到的最好的。我会等到赏金结束再选择你的答案,只是为了刺激其他人。 +1 只是为了好奇。你知道是否有可能改变解析器的行为?比如,测试类似: sum>>abs>>round>>c(1.5,-2.3,3.4) ? 并非没有extreme对R源代码的低级黑客攻击......例如您必须在低级 C 代码中找到解析代码并进行适当的修改。 有什么理由不将操作符定义为%&lt;%,表示数据是从右向左发送的? @ClausWilke 我认为这是一个不错的建议。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

backpipe 包就是为此目的而设计和创建的。它为 ma​​grittrpipeR 和通常为任何正向管道运算符提供了一个背管(从右到左)运算符。 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中从右到左的运算符关联性是不是可能?的主要内容,如果未能解决你的问题,请参考以下文章

在中缀表达式中反转运算符优先级

Python中从右到左的语言

如何解释这种运算符关联性?

逻辑运算的优先级

三元运算符既是左操作符又是右操作符..或两者都不是

c语言中条件运算 结合方向 从右到左 啥意思