问题描述
这个问题是对上一个答案的跟进,该答案提出了一个难题.
This question is a follow-up to a previous answer which raised a puzzle.
上一个答案的可重现示例:
Reproducible example from the 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 指出的那样?
The question is why does do.call(anova, Models)
work fine, as @Roland points out?
anova 的签名是 anova(object, ...)
The signature for anova is anova(object, ...)
anova
调用 UseMethod
,它应该*调用 anova.lm
,它应该调用 anova.lmlist
,它的第一行是 objects <- list(object, ...)
,但 object
在该公式中不存在.
anova
calls UseMethod
, which should* call anova.lm
which should call anova.lmlist
, whose first line is objects <- list(object, ...)
, but object
doesn't exist in that formulation.
我唯一能推测的是 do.call
可能不只是填充省略号,而是填充所有没有默认值的参数,并为省略号留下任何额外的内容?如果是这样,记录在哪里,因为它对我来说绝对是新的!
The only thing I can surmise is that do.call
might not just fill in ellipses but fills in all arguments without defaults and leaves any extra for the ellipsis to catch? If so, where is that documented, as it's definitely new to me!
* 这本身就是一个线索——如果第一个参数未指定,UseMethod
如何知道调用 anova.lm
?没有 anova.list
方法或 anova.default
或类似的...
* Which is itself a clue--how does UseMethod
know to call anova.lm
if the first argument is unspecified? There's no anova.list
method or anova.default
or similar...
推荐答案
在常规函数调用中 ...
按位置、部分匹配和完全匹配捕获参数:
In a regular function call ...
captures arguments by position, partial match and full match:
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
behaves in exactly the same way except instead of supplying the arguments directly to the function, they're stored in a list and do.call
takes care of passing them into the function:
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
这篇关于存在没有默认值的参数时 do.call() 的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!