五种 Magrittr 管道 %>%、%<>%、%$%、%!>% 和 %T>% 的区别和用例是什么?

What are the differences and use cases of the five Magrittr Pipes %>%, %<>%, %$%, %!>% and %T>%?

提问人:GKi 提问时间:5/25/2023 最后编辑:GKi 更新时间:5/26/2023 访问量:240

问:

Magrittr有那些不同的管道:

  • %>%
  • %<>%分配管道
  • %$%展览管
  • %!>%急切的管道
  • %T>%三通管

它们有什么区别和用例?

R Tidyverse Magrittr

答:

4赞 GKi 5/25/2023 #1

%>%

通过管道将对象转发到函数或调用表达式中。

library(magrittr)
1:10 %>% head()   # Basic use
#[1] 1 2 3 4 5 6
1:10 %>% head     # Works also
#[1] 1 2 3 4 5 6
#1:3 %>% approxfun(1:3, 4:6)  #But in this case empty parentheses are needed
#Error in if (is.na(method)) stop("invalid interpolation method") :
1:3 %>% approxfun(1:3, 4:6)()
#[1] 4 5 6

1:10 %>% head(3)  # Use with lhs as first argument
#[1] 1 2 3

"Ceci n'est pas une pipe" %>% gsub("une", "un", .)  # Using the dot place-holder
#[1] "Ceci n'est pas un pipe"

1:3 %>% paste0(LETTERS[.], 0)    # When dot is nested, lhs is still placed first
#[1] "1A0" "2B0" "3C0"
1:3 %>% {paste0(LETTERS[.], 0)}  # This can be avoided with {}
#[1] "A0" "B0" "C0"

Смотритетакже: 使用没有空括号的函数和 %>% magrittr 管道时有什么缺点?

%<>%分配管道

通过管道将对象转发到函数或调用表达式中,并使用结果值更新 lhs 对象。

x <- -2:2
x %<>% abs %>% sort
x  # 0 1 1 2 2

%$%展览管

将 lhs 中的名称公开给 rhs 表达式。当函数没有内置数据参数时,这很有用。

iris %$% cor(Sepal.Length, Sepal.Width)
#[1] -0.1175698

另请参阅:我应该使用 %$% 而不是 %>%?

%!>%急切的管道

从左到右评估。而 是懒惰的,只在需要时计算管道表达式,是 渴望并在每一步评估管道输入。此外,它还在同一环境中进行评估。%>%%!>%

0 %!>% (\(x) {cat(1); x}) %!>% (\(x) cat(2))  # Evaluates from left to right
#12
0 %>% (\(x) {cat(1); x}) %>% (\(x) cat(2))    # Evaluates only cat(2) as the first result is never used
#2

1 %!>% assign("a", .)  # Work
a
#[1] 1
0 %>% assign("a", .)   # Does not work as there is an additional environment
a
#[1] 1
0 %>% assign("a", ., envir=parent.env(environment())) # Give explicitly where to evaluate
a
#[1] 0

%T>%三通管

将值传递到函数或调用表达式中,并返回原始值而不是结果。当表达式用于其副作用(例如绘图或打印)时,这很有用。

matrix(1:4, 2) %T>% plot %>% sum  # sum gets the same data like plot
#[1] 10

另请参阅:magrigtr三通管%T>%等效

评论

2赞 Konrad Rudolph 5/25/2023
对于“基本用法”,可能值得注意的是,最广泛(?)推荐的约定(尽管最初的“magrittr”作者不同意这种偏好)是向RHS提供空括号,即写,因为否则在处理返回函数的函数时,符号会变得混乱/不一致。(正是由于这个原因,本机管道需要括号)。1:10 %>% head()|>
0赞 GKi 5/25/2023
谢谢,我已经改变了它,但他们以这种方式调用和使用它。请参阅示例或 magrittr.tidyverse.org/reference/pipe.html#ref-examples 。也许它来自,因为它也可以以这种形式使用,在这里通常只使用函数的名称,如 .?"%>%"`%>%`(1:5, sum)sapply(list(1:5), sum)
0赞 Konrad Rudolph 5/25/2023
就像我说的,原始包作者不同意这种普遍的偏好,但他是少数几个这样做的人之一,并且有很好的技术理由更喜欢函数调用之后,而反对它们的唯一原因是简洁性的胜利微乎其微。而且,值得注意的是,将函数调用表达式传递给管道操作与将函数传递给调用有根本的不同。两者在概念上非常不同。特别是工作和做一些不同于 的事情,对于一个适当定义的 .()sapply(1:5, f())sapply(1:5, f)f
0赞 GKi 5/26/2023
谢谢!我问了一个关于这个话题的问题:stackoverflow.com/questions/76335609