首页 > 解决方案 > 处理省略号参数中的缺失值......在R中

问题描述

如何处理...函数参数中的缺失值?

我有一个通用函数foo,它是我想与其他函数共享的样板代码(bar在这种情况下)。我也希望能够在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(...)之前引发错误。missing

我一直在看quosoresrlang但似乎没有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文档中本示例中处理缺失值的方式处理缺失值,但...不必is_missingbar. 我从文档中复制了下面的示例:

library(rlang)
fn <- function(arg) enquo(arg)
fn()
#> <quosure>
#> expr: ^
#> env:  empty
quo_is_missing(fn())
#> [1] TRUE

标签: rfunctionargumentsellipsisrlang

解决方案


我找到了解决我的问题的方法。这不是问题的真正解决方案,更多的是一种解决方法。它用于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()

reprex 包(v0.3.0)于 2021-01-27 创建


推荐阅读