将可选参数传递给函数,三个点

时间:2018-05-24 13:52:48

标签: r arguments ellipsis

我对...的工作方式感到困惑。

tt = function(...) {
  return(x)
}

为什么没有tt(x = 2)返回2

相反,它失败并出现错误:

  

tt(x = 2)出错:对象' x'找不到

即使我将x作为参数传递?

3 个答案:

答案 0 :(得分:6)

因为您在...中传递的所有内容都保留在...中。您传递的未通过参数显式捕获的变量不会扩展到本地环境中。 ...应该用于当前函数根本不需要与之交互的值,但是稍后的函数确实需要使用它们可以在...内轻松传递。它适用于像

这样的场景
ss <- function(x) {
   x
}

tt <- function(...) {
  return(ss(...))
}

tt(x=2)

如果您的函数需要定义变量x,那么它应该是一个参数

tt <- function(x, ...) {
  return(x)
}

如果你真的想将点扩展到当前环境中(我强烈建议你不要这样做),你可以做类似的事情

tt <- function(...) {
  list2env(list(...), environment())
  return(x)
}

答案 1 :(得分:2)

如果您将三个点定义为函数的参数并希望它起作用,则需要告诉您的函数实际出现的点。在您的示例中,您既未将x定义为参数,也未将...功能定义在函数体的其他位置。一个实际有效的例子是:

tt <- function(x, ...){
       mean(x, ...)
}

x <- c(1, 2, 3, NA)
tt(x)
#[1] NA
tt(x, na.rm = TRUE)
#[1] 2

此处...指的是函数mean可能采用的任何其他参数。另外你有一个常规的参数x。在第一个示例tt(x)中只返回mean(x),而在第二个示例tt(x, na.rm = TRUE)中,将第二个参数na.rm = TRUE传递给mean,以便tt返回mean(x, na.rm = TRUE)

答案 2 :(得分:1)

R的程序员使用的另一种方式是list(...),如

tt <- function(...) {
    args <- list(...)    # As in this
    if("x" %in% names(args))
        return(args$x)
    else
        return("Something else.")
}

tt(x = 2)
#[1] 2

tt(y = 1, 2)
#[1] "Something else."

我相信这是他们最喜欢的一种,如果不是 最喜欢的处理点参数的方法。