Ошибка при вызове `lm` в` lapply` с аргументом `weightights`

Я встречаю странное поведение при вызове lm внутри lapply с помощью аргумента weights.

Мой код состоит из списка формул, в котором я запускаю линейную модель, которую я вызываю в lapply. Пока он работал:

dd <- data.frame(y = rnorm(100),
                 x1 = rnorm(100),
                 x2 = rnorm(100),
                 x3 = rnorm(100),
                 x4 = rnorm(100),
                 wg = runif(100,1,100))

ls.form <- list(
  formula(y~x1+x2),
  formula(y~x3+x4),
  formula(y~x1|x2|x3),
  formula(y~x1+x2+x3+x4)
)

res.no.wg <- lapply(ls.form, lm, data = dd)

Однако, когда я добавляю аргумент weights, я получаю странную ошибку:

res.with.wg <- lapply(ls.form, lm, data = dd, weights = dd[,"wg"])
Error in eval(extras, data, env) : 
  ..2 used in an incorrect context, no ... to look in

Как будто ... из lapply противоречил ... вызова lm, но только из-за аргумента weights.

Любая идея была причиной этой проблемы и как ее исправить?

ПРИМЕЧАНИЕ: использование вызова без lapply работает как ожидалось:

lm(ls.form[[1]], data = dd, weights = dd[,"wg"] )

Call:
lm(formula = ls.form[[1]], data = dd, weights = dd[, "wg"])

Coefficients:
(Intercept)           x1           x2  
   -0.12020      0.06049     -0.01937  

РЕДАКТИРОВАТЬ Последний вызов - lapply в пределах function типа:

f1 <- function(samp, dat, wgt){
res.with.wg2 <- lapply(ls.form, function(x) {lm(formula = x, data=dat[samp,], weights=dat[samp,wgt])})
}

f1(1:66, dat=dd, wgt = "wg")

Ответ 1

В файле справки для lapply есть примечание:

По историческим причинам вызовы, создаваемые в результате, неоценимы, и код был написан (например, bquote), который опирается на это. Эта означает, что записанный вызов всегда имеет форму FUN (X [[i]],...), с заменой я на текущий (целочисленный или двойной) индекс. Это не обычно проблема, но может быть, если FUN использует sys.call или match.call или если это примитивная функция, которая использует вызов. Эта означает, что часто безопаснее называть примитивные функции с помощью обертка, так что, например, lapply (ll, function (x) is.numeric(x)) является требуется для отправки метода is.numeric правильно.

lm дважды использует match.call в своих первых строках:

cl <- match.call()
mf <- match.call(expand.dots = FALSE)

Решение, указанное в файле справки и @Florian, должно использовать анонимную оболочку функции.

Update

Для этой конкретной проблемы изменения формулы модели вы можете переписать, чтобы избежать вызова lm в lapply, используя update вместо этого:

# create base model (the formula here doesn't really matter, but we can specify the weights safely here)
baselm <- lm(y+x1,data=dd,weights=dd[,"wg"])
# update with lapply
lapply(ls.form,update,object=baselm)
[[1]]

Call:
lm(formula = y ~ x1 + x2, data = dd, weights = dd[, "wg"])

Coefficients:
(Intercept)           x1           x2  
    0.07561      0.16111      0.15014  

...

Ответ 2

Я не уверен, почему он не работает, но я думаю, что у меня есть исправление для вас:

res.with.wg2 <- lapply(ls.form, 
                   function(x) {lm(formula = x, data=dd, weights=dd[,"wg"])})

Надеюсь, это поможет!