提问人: 提问时间:3/29/2020 最后编辑:Ben 更新时间:5/29/2020 访问量:405
如何定义管道操作员?
How to define the pipe operator?
问:
我非常喜欢管道(在评论中提到的 dplyr 或 magrittr 中),但有时我会遇到错误,这表明我缺乏一些理解。对于其他函数或运算符,我至少对如何定义它们有一些想法,但是对于管道,如果我想定义它,我什至不知道从哪里开始。
我真的很好奇管道是如何定义的。到目前为止,我只是尝试将其分配给自己的操作员,但即使这样也不起作用。请看这里:
library(dplyr)
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
# gives an error: subscript out of bounds
哪些神奇的成分使烟斗起作用?我们自己如何定义它?谢谢。
答:
0赞
moodymudskipper
5/29/2020
#1
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 软件包 (v0.3.0) 于 2020-05-29 创建
评论
0赞
5/29/2020
谢谢! 显然是如何定义管道问题的答案。我不明白的是:我分配了显示的代码,在我的理解中,它应该制作管道,但它不起作用。我所做的是:magrittr:::pipe
magrittr:::
%>%
`%>%` <- function () { function(lhs, rhs) { parent <- parent.frame() env <- new.env(parent = parent) chain_parts <- split_chain(match.call(), env = env)...
0赞
moodymudskipper
5/29/2020
由于split_chains等未导出,因此新管道无法再访问它,因为您在全局环境中定义了它。这并不是 magrittr 特有的
上一个:R:同一列表中的引用列表项
评论