这个问题是对previous answer提出疑问的后续行动。
上一个答案的可重复示例:
Models <- list( lm(runif(10)~rnorm(10)),lm(runif(10)~rnorm(10)),lm(runif(10)~rnorm(10)) )
lm1 <- lm(runif(10)~rnorm(10))
library(functional)
# This works
do.call( Curry(anova, object=lm1), Models )
# But so does this
do.call( anova, Models )
问题是为什么do.call(anova, Models)
正常工作,正如@Roland指出的那样?
anova的签名是anova(object, ...)
anova
来电UseMethod
,应致电anova.lm
,呼叫anova.lmlist
,其第一行为objects <- list(object, ...)
,但object
不会不存在于那种表述中。
我唯一可以猜测的是do.call
可能不只是填充省略号而是填充所有参数而没有默认值,并留下任何额外的省略号来捕获?如果是这样,记录在哪里,因为它对我来说绝对是新的!
*这本身就是一个线索 - 如果第一个参数未指定,UseMethod
如何知道调用anova.lm
?没有anova.list
方法或anova.default
或类似方法......
答案 0 :(得分:4)
在常规函数中,...
通过位置,部分匹配和完全匹配来捕获参数:
f <- function(...) g(...)
g <- function(x, y, zabc) c(x = x, y = y, zabc = zabc)
f(1, 2, 3)
# x y zabc
# 1 2 3
f(z = 3, y = 2, 1)
# x y zabc
# 1 2 3
do.call
的行为方式完全相同,除了不直接向函数提供参数,它们存储在列表中,do.call
负责将它们传递给函数:
do.call(f, list(1, 2, 3))
# x y zabc
# 1 2 3
do.call(f, list(z = 3, y = 2, 1))
# x y zabc
# 1 2 3
答案 1 :(得分:2)
我认为值得强调的是列表元素的名称很重要。哈德利提到了它,但这可能是一个烦恼。考虑下一个例子:
x <- rnorm(1000)
y <- rnorm(1000)
z <- rnorm(1000) + 0.2
Models <- list()
Models$xy <- lm(z~x)
Models$yz <- lm(z~y)
# This will fail, because do.call will not assign anything to the argument "object" of anova
do.call(anova, Models)
# This won't
do.call(anova, unname(Models))
答案 2 :(得分:1)
do.call
将列表的第一个元素传递给第一个参数:
fun <- function(x,...) {
print(paste0("x=",x))
list(x, ...)
}
do.call(fun, list(1,2))
# [1] "x=1"
# [[1]]
# [1] 1
#
# [[2]]
# [1] 2