繁体   English   中英

R:为什么在省略号是最后一个参数时为省略号(...)提供列表不起作用?

[英]R: why providing a list to ellipsis (…) when ellipsis is the last argument does not work?

我正在编写一个利用省略号(又名... )的函数。 它允许您指定可变数量的其他参数。 我想提供一个带参数的列表作为附加参数。 以下是可重现的示例:

f <- function(..., a =1, b = 2){
  l <- list(...)
  print(l)
}
f(list(a = 2))

[[1]]
[[1]]$a
[1] 2

在列表中提供附加参数的目的是避免名称冲突( f的函数可以采用名为a的参数,我希望确保提供它的可能性)。

在更改实现时,我注意到将省略号移动到函数声明中的最后一个位置会返回不同的结果(即空列表):

g <- function(a =1, b = 2, ...){
  l <- list(...)
  print(l)
}
g(list(a = 2))

list()

好奇,我添加了两个函数的默认参数:

f <- function(..., a =1, b = 2){
  l <- list(...)
  print(l)
  print(c(a = a, b = b))
}
g <- function(a =1, b = 2, ...){
  l <- list(...)
  print(l)
  print(c(a = a, b = b))
}

f(list(a = 2)) # results of calling f
[[1]]
[[1]]$a
[1] 2


a b 
1 2

g(list(a = 2)) # results of calling g
list()
$a.a
[1] 2

$b
[1] 2

因此,第一个函数( f )返回预期的输出,但第二个函数( g )忽略(?)默认参数a并以某种方式修改了由省略号提供的列表。

我想了解为什么两个输出彼此不同。 这是否意味着只有当省略号是函数调用中的第一个参数时,才能将列表作为附加参数传递?

R中参数的工作方式是,当你没有命名你的第一个参数时,R只假设它进入函数的第一个参数。 对于参数列表中的第二个,第三个等参数,对于...之后的参数,这是正确的 - 因为R不知道您打算将多少个参数放入... ,如果您想要更改后面的任何内容的默认值,你必须命名它。

所以在你的情况下,当你调用函数f() ,对象list(a=2)进入... 但是在g() ,同一个对象进入了一个。 你可以得到某些东西的唯一方法...当它放在参数列表的末尾而不包括a和b的争论时,就是将它命名为非a或b的东西,例如g(c = list(a) = 1))。

我认为如果你不在函数调用中使用list ,函数会按预期工作: f(a=2)g(a=2)都会返回list()一个变量l的值。

由于您将列表作为参数传递,因此将其视为未命名变量,并将其分配给第一个形式参数,该参数对于fg是不同的。

如果你做do.call(f, list(a=2))do.call(g, list(a=2)) ,情况会有所不同。 在这种情况下,值2将被分配给预期的形式参数a

对你的问题的简短回答这是否意味着只有当省略号是函数调用中的第一个参数时,才能将列表作为附加参数传递? 是否,如果在函数调用期间传递值时遵循正确的命名或位置,则不会出现参数匹配不正确的问题。

最好在函数调用中命名参数(至少从第二个参数),因此正确的名称匹配与预期的效果一起发生。

在函数调用期间未提及名称将执行参数的位置匹配。 如果您未能在正确的位置发送正确的值,这可能会导致意外的影响。

请注意打印输出中参数名称的顺序。 它遵循函数中定义的参数顺序。 只有正确命名参数,才会发生正确的顺序。

正确遵循参数命名时,无需担心参数的位置。 你可以传递任何东西。 它不一定是list

f <- function(..., a =1, b = 2){
  mc <- match.call(expand.dots = TRUE )
  print(names(mc))
}
g <- function(a =1, b = 2, ...){
  mc <- match.call(expand.dots = TRUE )
  print(names(mc))
}

f(c1 = list(z = 2, f = 5), a = 1, b = 2)  # [1] ""   "c1" "a"  "b" 
f(a = 1, c1 = list(z = 2, f = 5), b = 2)  # [1] ""   "c1" "a"  "b"
f(a = 1, c1 = list(z = 2, f = 5), b = 2, c2 = 4) # ""   "c1" "c2" "a"  "b" 
f(c1 = list(z = 2, f = 5), 1, 2, 4) # [1] ""   "c1" ""   ""   ""  


g(c1 = list(z = 2, f = 5), a = 1, b = 2)  # [1] ""   "a"  "b"  "c1"
g(a = 1, c1 = list(z = 2, f = 5), b = 2)  # [1] ""   "a"  "b"  "c1"
g(a = 1, c1 = list(z = 2, f = 5), b = 2, c2 = 4) # [1] ""   "a"  "b"  "c1" "c2"
g(c1 = list(z = 2, f = 5), 1, 2, 4) # [1] ""   "a"  "b"  "c1" ""

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM