R的新原生管道`>`和magrittr管道`%>%`有什么区别?
在 R 4.1 中引入了一个本地管道运算符,它比以前的实现“更加精简”。我已经注意到 native|>和 magrittr pipe之间的一个区别%>%,即2 %>% sqrt可以工作但2 |> sqrt不能,并且必须写为2 |> sqrt(). 使用新的管道运算符时是否有更多差异和陷阱需要注意?
回答
它们两者之间的另一个区别是在值管道.可被用作在一个占位符magrittr的管
c("dogs", "cats", "rats") %>% grepl("at", .)
#[1] FALSE TRUE TRUE
但这对于 R 的原生管道是不可能的。
c("dogs", "cats", "rats") |> grepl("at", .)
grepl(c("dogs", "cats", "rats"), "at", .) 中的错误:对象 '.' 未找到
以下是引用它们的不同方法 -
- 编写一个单独的函数 -
find_at = function(x) grepl("at", x)
c("dogs", "cats", "rats") |> find_at()
#[1] FALSE TRUE TRUE
2 一个。使用匿名函数 -
c("dogs", "cats", "rats") |> {function(x) grepl("at", x)}()
2 湾。使用新的匿名函数语法
c("dogs", "cats", "rats") |> {(x) grepl("at", x)}()
示例取自 - https://www.jumpingrivers.com/blog/new-features-r410-pipe-anonymous-functions/
回答
|>R 4.1.0 中添加的基础 R 管道“只是”执行功能组合。即我们可以看到它的使用真的和函数调用一样:
> 1:5 |> sum() # simple use of |>
[1] 15
> deparse(substitute( 1:5 |> sum() ))
[1] "sum(1:5)"
>
这有一些后果:
- 它使它更快一点
- 它使它更简单,更健壮
- 它使限制性更强:
sum()这里需要括号才能正确调用 - 它限制了“隐式”数据参数的使用
这导致可能使用=>当前“可用但未激活”(为此您需要设置环境变量_R_USE_PIPEBIND_,并且可能会在 R 4.2.0 中更改)。
(这首先是作为一个问题的答案在这里复制的,我只是按照建议复制了它。)
编辑:随着关于“是什么=>”的后续问题出现,这里是一个快速跟进。请注意,此运算符可能会发生变化。
> Sys.setenv("_R_USE_PIPEBIND_"=TRUE)
> mtcars |> subset(cyl == 4) |> d => lm(mpg ~ disp, data = d)
Call:
lm(formula = mpg ~ disp, data = subset(mtcars, cyl == 4))
Coefficients:
(Intercept) disp
40.872 -0.135
> deparse(substitute(mtcars |> subset(cyl==4) |> d => lm(mpg ~ disp, data = d)))
[1] "lm(mpg ~ disp, data = subset(mtcars, cyl == 4))"
>
在deparse(substitute(...))这里特别漂亮。
回答
本机管道是作为语法转换实现的,因此2 |> sqrt()与 相比没有明显的开销sqrt(2),而2 %>% sqrt()有一个小的惩罚。
microbenchmark(sqrt(1),
2 |> sqrt(),
3 %>% sqrt())
# Unit: nanoseconds
# expr min lq mean median uq max neval
# sqrt(1) 117 126.5 141.66 132.0 139 246 100
# sqrt(2) 118 129.0 156.16 134.0 145 1792 100
# 3 %>% sqrt() 2695 2762.5 2945.26 2811.5 2855 13736 100
您会看到2 |> sqrt()传递给的表达式如何microbenchmark被解析为sqrt(2). 这也可以在
quote(2 |> sqrt())
# sqrt(2)