[英]Deal with missing values in ellipsis arguments … in R
您如何处理 function 的参数...
中的缺失值?
我有一个通用的 function foo
它是我想与其他功能共享的样板代码(在这种情况下为bar
)。 我还希望能够在缺少 arguments 的情况下运行bar()
。
问题是当我使用list(...)
时,缺失值会引发错误:
foo = function(...){
list(...)
}
bar = function(name){
foo(name=name)
}
bar("a")
#> $name
#> [1] "a"
bar()
#> Error in foo(name = name): argument "name" is missing, with no default
这里的问题是list(...)
强制评估所有 arguments 并在我执行任何missing
的测试之前引发错误。
我一直在查看rlang中的rlang
,但is_missing
和quo_is_missing
似乎不适用于...
。
library(rlang)
foo = function(...){
lapply(rlang::enquos(...), is_missing)
}
bar("a")
#> $name
#> [1] FALSE
bar()
#> $name
#> [1] FALSE
foo = function(...){
lapply(rlang::enquos(...), quo_is_missing)
}
bar("a")
#> $name
#> [1] FALSE
bar()
#> $name
#> [1] FALSE
并且tidy_eval
失败并出现同样的错误:
foo = function(...){
lapply(rlang::enquos(...), eval_tidy)
}
bar("a")
#> $name
#> [1] "a"
bar()
#> Error in FUN(X[[i]], ...): argument "name" is missing, with no default
为了澄清,我想处理缺失值的方式,就像在本例中从quosore文档但在...
中处理它们的方式一样,而不必为bar
中的每个参数指定is_missing
。 我从文档中复制了下面的示例:
library(rlang)
fn <- function(arg) enquo(arg)
fn()
#> <quosure>
#> expr: ^
#> env: empty
quo_is_missing(fn())
#> [1] TRUE
就像评论说的那样-问题不在于list(...)
而在于bar(name)
。 您定义了一个带参数的 function,并且您在没有任何 arguments 的情况下调用该 function,因此出现错误。
如果你想让bar()
工作,即使参数name
丢失,你可以使用missing()
:
bar = function(name){
if(missing(name)) {
foo()
} else {
foo(name=name)
}
}
现在bar()
工作:
> bar()
list()
编辑后:问题似乎是list(...)
强制name
被评估,然后它看到bar()
没有看到任何name
。 也许在您的情况下捕获对父 function bar()
的调用有意义?:
foo = function(...) {
as.list(sys.call(1))[-1]
}
bar = function(name){
foo(name=name)
}
> bar()
list()
> bar(name="a")
$name
[1] "a"
我找到了解决我的问题的方法。 这不是问题的真正解决方案,更多的是一种解决方法。 它使用tryCatch
将...
中的缺失值转换为NULL
。 如果有人觉得有用,我会在这里发布。
library(rlang)
ellipsis_to_list = function(...){
args_names = call_args_names(match.call())
args_list = list()
range = 0:...length()
range = range[-1]
for(i in seq_along(range)){
v = tryCatch(...elt(i),
error=function(e){
if(grepl("missing", e$message)) NULL
else stop(e$message)
})
args_list = c(args_list, list(v))
}
names(args_list) = args_names
args_list
}
foo = function(...){
args_list = ellipsis_to_list(...)
args_list[ ! sapply(args_list, is.null)]
}
boo = function(name){
foo(name=name)
}
boo("a")
#> $name
#> [1] "a"
boo()
#> named list()
由代表 package (v0.3.0) 于 2021 年 1 月 27 日创建
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.