如何在R中实现F#的前向管道运算符?该运算符使得轻松地链接一系列计算成为可能。例如,当你有一个输入data
并想要按顺序调用函数foo
和bar
时,你可以这样写:
data |> foo |> bar
不要写成bar(foo(data))
。好处是你可以避免一些括号,计算的顺序和执行的顺序(从左到右)保持一致。在F#中,该运算符定义如下:
let (|>) a f = f a
似乎可以使用 %...% 作为二进制运算符,但这将如何工作?
如何在R中实现F#的前向管道运算符?该运算符使得轻松地链接一系列计算成为可能。例如,当你有一个输入data
并想要按顺序调用函数foo
和bar
时,你可以这样写:
data |> foo |> bar
不要写成bar(foo(data))
。好处是你可以避免一些括号,计算的顺序和执行的顺序(从左到右)保持一致。在F#中,该运算符定义如下:
let (|>) a f = f a
似乎可以使用 %...% 作为二进制运算符,但这将如何工作?
我不知道它在实际使用中能否很好地保持,但这似乎(?)可以做到你想要的,至少对于单参数函数而言...
> "%>%" <- function(x,f) do.call(f,list(x))
> pi %>% sin
[1] 1.224606e-16
> pi %>% sin %>% cos
[1] 1
> cos(sin(pi))
[1] 1
顺带一提,截至目前(2021年12月3日),除了magrittr
/tidyverse管道符(%>%
)外,在R中还有一个本地管道符|>
(以及一个在开发版中可以启用的试验性=>
运算符):例如,请参见这里。
do.call
可能是多余的 -- 函数体可能只需要是 f(x)
,但如果你想要允许多个参数类似于 list(1,5) %>% [back-quote]x[back-quote]
,那么你就需要使用 do.call
... - Ben Bolker编辑:包现在已经提交到CRAN。包含示例。
magrittr包专门为此而设计。
install.packages("magrittr")
示例:
iris %>%
subset(Sepal.Length > 5) %>%
aggregate(. ~ Species, ., mean)
还有,请参阅vignette:http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html如果你喜欢F#管道,它具有很多有用的功能,而谁不喜欢呢?!
fp = function(x, f) f(x)
这将执行调用,例如:
> fp(4, print)
[1] 4
这个等价,但在非元组情况下不能像 4 |> f x y
这样使用,因为 R 中没有这种语法。你可以尝试模仿 F# 的函数式行为,但会很笨拙:
fp = function(x, f, ...) function(...) f(x, ...)
> tri = function(x, y, z) paste(x,y,z)
> fp("foo", fp("mar", tri))("bar")
[1] "mar foo bar"
fp
替换为中缀符号:`%>%` = function(x, f) f(x)
> 1:10 %>% range %>% mean
[1] 5.5