在函数中将缺少的参数从函数传递给函数

时间:2015-07-22 08:27:36

标签: r arguments function-calls

我已经了解到在函数中使用可选参数并通过missing()检查它们的常见做法 (例如SO 22024082中所述)

在这个例子中,round0是可选参数(我知道,round0可以定义为逻辑)。

foo = function(a, round0) {
    a = a * pi
    if(!missing(round0)) round(a)
    else a
}

但是,如果我从另一个函数调用此函数,我该如何传递“missing”?

bar = function(b) {
    if(b > 10) round1=T
    foo(b, round1)
}

如果b < 10然后bar()中的round1未定义,但无论如何都传递给foo。如果我修改foo():

foo = function(a, round0) {
    a = a * pi
    print(missing(round0))
    print(round0)
    if(!missing(round0)) round(a)
    else a
}

并运行bar(9)输出为:

bar(9)
[1] FALSE
Error in print(round0) : object 'round1' not found
Called from: print(round0)

这意味着:round0没有丢失,但也无法访问?

我不想在bar()中使用不同的函数调用,如果foo()中有几个可选参数,我将不得不为每个缺失/不丢失编写一个函数调用 - 所有可选参数的组合。

是否可以通过“缺失”,或者其他解决方案适用于此问题?

4 个答案:

答案 0 :(得分:7)

在您的示例中,round0不会丢失,它被设置为round1未定义(而不是丢失)。

一般来说,最好的方法是使用默认值,例如FALSE

foo = function(a, round0 = FALSE) {
    a = a * pi
    if (!round0) round(a)
    else a
}

bar = function(b) {
    round1 <- FALSE
    if (b > 10) round1=TRUE
    foo(b, round1)
}

或无法在参数列表中轻松表达默认值:

foo = function(a, round0 = NULL) {
    a = a * pi
    if(!is.null(round0)) round(a)
    else a
}

bar = function(b) {
    round1 <- NULL
    if (b > 10) round1=TRUE
    foo(b, round1)
}

请注意,在这两种情况下,您都需要在调用函数中手动将参数设置为默认值。

如果您需要foo声明,也可以在有或没有参数的情况下调用if函数:

bar = function(b) {
    if (b > 10) foo(b, TRUE) else foo(b)
}

但是你不能(据我所知)创建一个变量missing,而不仅仅是将它作为参数传递。

答案 1 :(得分:3)

我最近遇到了类似的问题,并希望以一般方式解决它。我认为可以按照下面函数//ul/li[last()] 的定义所示完成:

g()

以下是使用不同参数集调用f <- function(a = 5, b = 3, c = 2, d = 7) { if (missing(a)) {print("a is missing.")} if (missing(b)) {print("b is missing.")} if (missing(c)) {print("c is missing.")} if (missing(d)) {print("d is missing.")} cat(a, b, c, d) } g <- function(a = 1, b = 1, c = 1, d = 1) { args <- as.list(match.call()) args[[1]] <- NULL # remove first list element, it's the function call do.call(f, args, envir = parent.frame()) } 时得到的结果:

g()

如果您不想将所有参数传递给下一个函数或想要添加一些参数,可以添加或删除> g() [1] "a is missing." [1] "b is missing." [1] "c is missing." [1] "d is missing." 5 3 2 7 > g(a = 3) [1] "b is missing." [1] "c is missing." [1] "d is missing." 3 3 2 7 > g(b = 10, c = 10) [1] "a is missing." [1] "d is missing." 5 10 10 7 列表。例如,请参阅以下函数args,它以一般方式执行此操作:

g()

以下是使用不同参数集调用g <- function(a = 1, b = 1, c = 1, x = 1, y = 1, z = 1) { f_args <- c("a", "b", "c") # arguments we want to hand off to function f # obtain the list of arguments provided args <- as.list(match.call()) # remove first list element, it's the function call args[[1]] <- NULL # remove the arguments that are not listed in f_args args <- args[na.omit(match(f_args, names(args)))] # now add argument d, we always want it to be 0: args <- c(args, list(d = 0)) do.call(f, args, envir = parent.frame()) } 时得到的结果:

g()

有关> g() [1] "a is missing." [1] "b is missing." [1] "c is missing." 5 3 2 0 > g(a = 3) [1] "b is missing." [1] "c is missing." 3 3 2 0 > g(b = 10, c = 10) [1] "a is missing." 5 10 10 0 的更多信息,请参阅this answer

答案 2 :(得分:1)

您可以使用不带参数的substitute()创建丢失的对象。

在您的情况下,我们可以在round1子句中使else成为丢失的对象:

foo = function(a, round0) {
  a = a * pi
  if(!missing(round0)) round(a)
  else a
}

bar = function(b) {
  if(b > 10) round1=T else round1 <- substitute()
  foo(b, round1)
}

bar(9)
#> [1] 28.27433

reprex package(v0.3.0)于2019-10-24创建

答案 3 :(得分:0)

rlang还提供了使参数丢失的函数missing_arg()

foo = function(a, round0) {
  a = a * pi
  if(!missing(round0)) round(a)
  else a
}

bar = function(b) {
  if(b > 10) round1 <- TRUE else round1 <- rlang::missing_arg()
  foo(b, round1)
}

foo(9)
#> [1] 28.27433
bar(9)
#> [1] 28.27433

reprex package(v0.3.0)于2020-12-02创建