使用“权重”参数在“lapply”中调用“lm”时出错

Error in calling `lm` in a `lapply` with `weights` argument

我在使用 weights 参数在 lapply 中调用 lm 时遇到了一个奇怪的行为。

我的代码包含一个公式列表,我在 运行 中调用了一个线性模型 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  

EDIT 最后调用是 function 中的 lapply 类型:

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")

我不太确定为什么它不起作用,但我认为我有一个修复程序:

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

希望对您有所帮助!

lapply 的帮助文件中有注释:

For historical reasons, the calls created by lapply are unevaluated, and code has been written (e.g., bquote) that relies on this. This means that the recorded call is always of the form FUN(X[[i]], ...), with i replaced by the current (integer or double) index. This is not normally a problem, but it can be if FUN uses sys.call or match.call or if it is a primitive function that makes use of the call. This means that it is often safer to call primitive functions with a wrapper, so that e.g. lapply(ll, function(x) is.numeric(x)) is required to ensure that method dispatch for is.numeric occurs correctly.

lm 在开头的行中使用了两次 match.call

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

帮助文件和@Florian 指出的解决方案是使用匿名函数包装器。

更新

对于这个改变模型公式的具体问题,你可以重写以避免在lapply中调用lm,使用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  

...