测试多个缺失参数。

3

假设我有一个由26个参数组成的函数(全部都是可选的),这些参数必须默认为NULL

missingStuff <- function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o , p,
                          q, r, s, t, u, v, w, x, y, z) {
...
}

我可以像这样测试每个实例

,例如


missingStuff <- function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o , p,
                          q, r, s, t, u, v, w, x, y, z) {

if(missing(a)) a <- NULL
if(missing(b)) b <- NULL
...
}

或者我可以将它们默认为NULL

missingStuff <- function (a = NULL, b = NULL, c = NULL, d = NULL, e = NULL,
                          f = NULL, g = NULL, h = NULL, i = NULL, j = NULL, 
                          k = NULL, l = NULL, m = NULL, n = NULL, o = NULL,
                          p = NULL, q = NULL, r = NULL, s = NULL, t = NULL,
                          u = NULL, v = NULL, w = NULL, x = NULL, y = NULL,
                          z = NULL) {
...
}

但这两种选项都很繁琐且有些混乱。我真的找不到一个合适的方式来做这个。也许可以使用formals()来更实际地完成这个任务。
这种方法不起作用,无论if语句如何,它都会将所有内容赋值为NULL
missingStuff <- function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o , p,
                          q, r, s, t, u, v, w, x, y, z) {

  lapply(formals(), function(x) {
    if(missing(x)) x <- NULL
    })
}

同样的,也不会

missingStuff <- function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o , p,
                          q, r, s, t, u, v, w, x, y, z) {

  lapply(formals(), function(x) {
    if(x == "") x <- NULL
    })
}

尽管
formals(missingStuff)[1] == ""
   a 
TRUE

我错过了什么吗?

你在这里到底想做什么? - mtoto
2
你已经在代码中完成了这个操作,或者我可以将它们默认设置为NULL。 - mtoto
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - RHertel
1
我认为有一些小问题。你正在从另一个函数中调用 missing,这可能会混淆名称和字符值等。虽然不太美观,但它可能适合你:for (x in setdiff(names(formals()), names(as.list(match.call()[-1])))) assign(x, value=NULL) - lukeA
3
我不同意你的观点,认为显式赋值并不会造成“混乱”。如果一切都在函数的formals中清晰地默认为NULL,对其他用户来说更加明确。话虽如此,我难以想象有哪个函数需要26个输入参数。这就是...的用途——可选参数,除非被调用,否则可以忽略。或者,考虑到参数太多,你也可以要求传递一个list变量到你的函数中,并创建一个默认变量,其全部为 NULL。 - Carl Witthoft
显示剩余2条评论
3个回答

0

你可以尝试使用 eval

missingStuff <- function (a, b, c, d, e, f)
{
  lapply(names(formals()), function(x)
  { eval(parse(text = paste0("if (missing(",x,")) {assign(\"",x,"\",NULL)}")), envir = parent.env(environment())) } )

  # print them
  for(name in names(formals())) { print(get(name)) }
}

missingStuff(a=1,f=4)

执行时,返回:

> missingStuff(a=1,f=4)
[1] 1
NULL
NULL
NULL
NULL
[1] 4

0

你应该使用sys.call或match.call来提取传递的参数。 然后,您可以设置不同的条件并更新所需的值。

missingStuff <- function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o , p,
                      q, r, s, t, u, v, w, x, y, z) {


  # get the names of the passed variables
  var <- names(as.list( sys.call() ))[-1]


  # set all the variables that arent passed to NULL
  for(i in 1:length(setdiff(names(formals(missingStuff)),var))){
    assign(setdiff(names(formals(missingStuff)),var)[i],NULL)
  }

  # set all the arguments that are passed as "" or NULL as NULL
  for(i in 1:length(var[mget(var)=="" | is.null(mget(var))])){
    assign(var[mget(var)==""][i],NULL)
  }

  # print all the values of the arguments
  mget(names(formals(missingStuff)))
}

例如运行:

missingStuff(a=,b=5,c=NULL)

你将会得到参数的打印:

> missingStuff(a=,b=5,c=NULL)
$a
NULL

$b
[1] 5

$c
NULL

$d
NULL
...

0

这里有另一种方法。我们过滤掉形参中未在调用中找到的参数,因此我们得到一个缺失参数列表,然后将NULL赋值给所有缺失参数,并将列表元素分配给本地环境。

missingStuff <- function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o , p,
                          q, r, s, t, u, v, w, x, y, z) {
  fmls <- formals()
  missing_fmls <- fmls[!names(fmls) %in% names(match.call()[-1])]
  missing_fmls[] <- list(NULL)
  list2env(missing_fmls, environment())

  print(b)
  print(r)

}
missingStuff()
#> NULL
#> NULL

2019年10月24日创建,使用reprex package(v0.3.0)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接