如何定义管道操作符?
How to define the pipe operator?
我非常喜欢管道(如评论中所述,在 dplyr or magrittr 中)但有时我 运行 会出错,这表明我缺乏一些理解。对于其他函数或运算符,我大多至少知道如何定义它们,但对于管道,如果我想定义它,我什至不知道从哪里开始。
我很好奇管道是怎么定义的。到目前为止,我只是试图将它分配给自己的操作员,但即使这样也行不通。看这里:
library(dplyr)
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
# gives an error: subscript out of bounds
是什么神奇的成分让管道发挥作用?我们如何自己定义它?谢谢
magrittr 的代码本身会检查您使用的管道是否被命名为少数允许的名称之一,如顶部所示:https://github.com/tidyverse/magrittr/blob/master/R/is_something.R .
事实上,所有管道都有相同的代码,从 magrittr:::pipe
复制而来,如脚本底部所示:
https://github.com/tidyverse/magrittr/blob/master/R/pipe.R
行为取决于管道的名称,这真的很奇怪,我从未在其他任何地方见过这种情况。
我会尝试通过发明一个行为类似的假函数来减少混淆,请原谅这个例子的愚蠢。
concat <- function(x,y) {
# extract quoted function name from call
fun <- sys.call()[[1]]
# check if it's one of our possible names, and act accordingly
if(identical(fun, quote(`%upconcat>%`))) {
return(toupper(paste0(x,y)))
}
if(identical(fun, quote(`%lowconcat>%`))) {
return(tolower(paste0(x,y)))
}
stop("Unsupported operator!")
}
`%upconcat>%` <- `%lowconcat>%` <- concat
"XoX" %upconcat>% "oXo"
#> [1] "XOXOXO"
"XoX" %lowconcat>% "oXo"
#> [1] "xoxoxo"
`%foo>%` <- `%upconcat>%`
"XoX" %foo>% "oXo"
#> Error in "XoX" %foo>% "oXo": Unsupported operator!
你看没有办法复制管道,除非你修改 is_pipe
函数本身,你不能这样做...
开个玩笑,当然可以,但可能不应该?
library(magrittr)
is_pipe <- function(pipe) {
identical(pipe, quote(`%>%`)) ||
identical(pipe, quote(`%T>%`)) ||
identical(pipe, quote(`%<>%`)) ||
identical(pipe, quote(`%$%`)) ||
identical(pipe, quote(`%pipe%`)) # <- added line
}
assignInNamespace("is_pipe", is_pipe, "magrittr")
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
#> [1] "data.frame"
由 reprex package (v0.3.0)
于 2020-05-29 创建
我非常喜欢管道(如评论中所述,在 dplyr or magrittr 中)但有时我 运行 会出错,这表明我缺乏一些理解。对于其他函数或运算符,我大多至少知道如何定义它们,但对于管道,如果我想定义它,我什至不知道从哪里开始。
我很好奇管道是怎么定义的。到目前为止,我只是试图将它分配给自己的操作员,但即使这样也行不通。看这里:
library(dplyr)
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
# gives an error: subscript out of bounds
是什么神奇的成分让管道发挥作用?我们如何自己定义它?谢谢
magrittr 的代码本身会检查您使用的管道是否被命名为少数允许的名称之一,如顶部所示:https://github.com/tidyverse/magrittr/blob/master/R/is_something.R .
事实上,所有管道都有相同的代码,从 magrittr:::pipe
复制而来,如脚本底部所示:
https://github.com/tidyverse/magrittr/blob/master/R/pipe.R
行为取决于管道的名称,这真的很奇怪,我从未在其他任何地方见过这种情况。
我会尝试通过发明一个行为类似的假函数来减少混淆,请原谅这个例子的愚蠢。
concat <- function(x,y) {
# extract quoted function name from call
fun <- sys.call()[[1]]
# check if it's one of our possible names, and act accordingly
if(identical(fun, quote(`%upconcat>%`))) {
return(toupper(paste0(x,y)))
}
if(identical(fun, quote(`%lowconcat>%`))) {
return(tolower(paste0(x,y)))
}
stop("Unsupported operator!")
}
`%upconcat>%` <- `%lowconcat>%` <- concat
"XoX" %upconcat>% "oXo"
#> [1] "XOXOXO"
"XoX" %lowconcat>% "oXo"
#> [1] "xoxoxo"
`%foo>%` <- `%upconcat>%`
"XoX" %foo>% "oXo"
#> Error in "XoX" %foo>% "oXo": Unsupported operator!
你看没有办法复制管道,除非你修改 is_pipe
函数本身,你不能这样做...
开个玩笑,当然可以,但可能不应该?
library(magrittr)
is_pipe <- function(pipe) {
identical(pipe, quote(`%>%`)) ||
identical(pipe, quote(`%T>%`)) ||
identical(pipe, quote(`%<>%`)) ||
identical(pipe, quote(`%$%`)) ||
identical(pipe, quote(`%pipe%`)) # <- added line
}
assignInNamespace("is_pipe", is_pipe, "magrittr")
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
#> [1] "data.frame"
由 reprex package (v0.3.0)
于 2020-05-29 创建