【发布时间】:2020-09-22 21:47:49
【问题描述】:
有没有办法让函数检测 magrittr 管道是否已将数据传递到其中?
一个激励的例子:
ifelse() 等某些函数不适用于 magrittr 输入。
1:4 %>% ifelse(. < 3, "low", "high")
#> Error in ifelse(., . < 3, "low", "high") : unused argument ("high")
导致错误。
要使功能按预期工作,您必须使用
1:4 %>% {ifelse(. < 3, "low", "high")}
#> "low" "low" "high" "high"
有没有办法重新定义一个函数,使其在管道输入时表现不同?
我的最佳尝试:
my_ifelse <- function(...) {
args <- list(...)
if (sys.call()[[2]] == ".") args <- args[-1]
ifelse(test = args[[1]], yes = args[[2]], no = args[[3]])
}
1:4 %>% my_ifelse(. < 3, "low", "high")
#> "low" "low" "high" "high"
这个解决方案有什么问题吗?会不会意外坏掉?
编辑:显然,如果传递的参数数量不正确,这将返回错误。更成熟的方法会尝试提供信息错误,甚至可能允许使用参数名称而不是 ...
【问题讨论】:
-
未经测试,但我认为
my_ifelse <- function(x, ...) ifelse(...)应该可以工作。如果没有丢失,我相信你的不起作用。 -
@Moody_Mudskipper 这是一个出色而简单的解决方案!一个缺点是,当它没有通过管道传输时,它无法复制通常的 ifelse() 功能。但是,如果您知道该函数将始终通过管道传输,那么这比我的通行证要好得多!
-
您也可以定义自己的不插入隐式点的管道:
"%>>%" <- function(lhs, rhs) eval(substitute(rhs), envir = list(. = lhs), enclos = parent.frame())