我在某些函数中使用tidyselection,我必须将第一个参数与省略号连接起来,因为它可能是一个需要特定处理的特定类。
正常的行为是:
foo = function(x, ...){
xloc = eval_select(expr(c(x, ...)), data = iris)
return(xloc)
}
foo(everything())当everything()是NULL时,我希望将它作为默认值(由于某种原因,x不能将它直接放在标头中,)。
不幸的是,这种语法是不允许的:
bar = function(x, ...){
if(is_null(x))
x=everything() #throws an error
xloc = eval_select(expr(c(x, ...)), data = iris)
return(xloc)
}
bar(NULL)
# Error: `everything()` must be used within a *selecting* function.
# i See <https://tidyselect.r-lib.org/reference/faq-selection-context.html>.我试着用我知道的所有“神秘”函数包装everything():parse,deparse,call,substitute,quo,sym,enquo,ensym,.什么都没有用(你在这里可以看出,我对这些不太精通)。
使用什么表达式可以替换第二个代码块中的x=everything() 行以使该函数工作?
版本:
发布于 2020-03-23 07:52:18
首先,您需要通过x传递{{,否则tidyselect无法检查参数,而且某些特性不能正常工作。然后你可以给它一个默认的everything()
foo <- function(x = everything(), ...) {
eval_select(expr(c({{ x }}, ...)), data = iris)
}
foo(everything())
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 2 3 4 5
foo()
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 2 3 4 5如果由于某种原因可以使用默认参数,请手动解除everything(),然后使用!!强制使用
foo <- function(x = NULL, ...) {
x <- enquo(x)
if (quo_is_null(x)) {
x <- expr(everything())
}
eval_select(expr(c(!!x, ...)), data = iris)
}发布于 2020-03-22 20:41:49
我们可以将everything封装在eval_select中
bar <- function(x, ...){
xloc <- tidyselect::eval_select(expr(c(x, ...)), data = iris)
if(length(xloc) == 0) {
xloc <- tidyselect::eval_select(expr(everything()), data = iris)
}
xloc
}
bar(1:2)
#Sepal.Length Sepal.Width
# 1 2
bar(NULL)
#Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 2 3 4 5 或者我们可以在if/else中使用expr条件
bar <- function(x, ...) {
x1 <- expr(c(if(is_null(x)) everything() else x, ...))
tidyselect::eval_select(x1, data = iris)
}
bar(everything())
#Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 2 3 4 5
bar(NULL)
#Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 2 3 4 5 https://stackoverflow.com/questions/60804580
复制相似问题