Ответ 1
Одна из причин, которая здесь имеет значение, заключается в том, что match.call
захватывает язык вызова без его оценки, и в этом случае он позволяет lm
обрабатывать некоторые "отсутствующие" переменные как "необязательные". Рассмотрим:
lm(x ~ y, data.frame(x=1:10, y=runif(10)))
Vs:
lm2 <- function (
formula, data, subset, weights, na.action, method = "qr",
model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
contrasts = NULL, offset, ...
) {
mf <- model.frame(
formula = formula, data = data, subset = subset, weights = weights
)
}
lm2(x ~ y, data.frame(x=1:10, y=runif(10)))
## Error in model.frame.default(formula = formula, data = data, subset = subset, :
## invalid type (closure) for variable '(weights)'
В lm2
, поскольку weights
"отсутствует", но вы все еще используете его в weights=weights
, R пытается использовать функцию stats::weights
, которая явно не та, что была предназначена. Вы можете обойти это, проверив пропущенность, прежде чем называть model.frame
, но в этот момент match.call
начинает выглядеть довольно хорошо. Посмотрите, что произойдет, если мы debug
вызываем:
debug(lm2)
lm2(x ~ y, data.frame(x=1:10, y=runif(10)))
## debugging in: lm2(x ~ y, data.frame(x = 1:10, y = runif(10)))
## debug at #5: {
## mf <- model.frame(formula = formula, data = data, subset = subset,
## weights = weights)
## }
Browse[2]> match.call()
## lm2(formula = x ~ y, data = data.frame(x = 1:10, y = runif(10)))
match.call
не содержит отсутствующих аргументов.
Можно утверждать, что необязательные аргументы должны были быть явно необязательными с использованием значений по умолчанию, но это не то, что здесь произошло.