Mur*_*rta 21 wolfram-mathematica r associativity magrittr
我是R的新手,我刚刚发现我患有Bracket Phobia(请参阅链接中的评论).我喜欢magrittr表示法的%>%工作方式,因为它在某些情况下避免了嵌套的括号,并使代码更具可读性.我来自Mathematica哪里,有一个非常相似的原生//符号来做什么%>%.以下是一些R和Mathematica比较:
#R Notation
c(1.5,-2.3,3.4) %>% round %>% abs %>% sum
Run Code Online (Sandbox Code Playgroud)
#Mathematica Notation
{1.5,-2.3,3.4}//Round//Abs//Total
Run Code Online (Sandbox Code Playgroud)
到目前为止很好,但是,我的问题是:
有没有办法模仿Mathematica @ notation,从右到左的关联性R?
以下是它在Mathematica中的工作原理,以解决上面相同的代码:
Total@Abs@Round@{1.5,-2.3,3.4}
Run Code Online (Sandbox Code Playgroud)
在Mathematica中,它也可以写成:
Total[Abs[Round[{1.5,-2.3,3.4}]]]
Run Code Online (Sandbox Code Playgroud)
就像R它会是:
sum(abs(round(c(1.5,-2.3,3.4))))
Run Code Online (Sandbox Code Playgroud)
但是在这样的事情中会更加干净(而且很酷)R:
sum@abs@round@c(1.5,-2.3,3.4)
Run Code Online (Sandbox Code Playgroud)
PS:我知道@用于S4课程,并不是一个好主意.这只是一个说明性的比较.
Ben*_*ker 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)
Run Code Online (Sandbox Code Playgroud)
语法不如能够@为合成运算符使用单个字符(例如),但即使你可以找到一个未使用的字符(所有明显的字符[!@#$%^&*~|]都被采用,掩盖它们将是一个可怕的想法)解析器限制:R中的用户定义二进制运算符必须是表单形式%?%.
如何使用composehadley的purrr包装?
compose(sum,abs,round,c)(1.5,-2.3,3.4)
Run Code Online (Sandbox Code Playgroud)
该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
)
Run Code Online (Sandbox Code Playgroud)
backpipe也不受@ BenBolker解决方案的附加参数的限制.例如,这适用于背管:
mean(na.rm=TRUE) %<% c(1:3,NA)
Run Code Online (Sandbox Code Playgroud)
另请参阅讨论此问题的magrittr github问题的讨论.