使用`weights`参数在`lapply`中调用`lm`时出错

Bas*_*ien 10 r lapply lm

lmlapply使用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)
Run Code Online (Sandbox Code Playgroud)

但是,当我添加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
Run Code Online (Sandbox Code Playgroud)

这就像如果...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  
Run Code Online (Sandbox Code Playgroud)

编辑 最终调用是lapplyfunction以下类型之内:

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")
Run Code Online (Sandbox Code Playgroud)

Flo*_*ian 11

我不确定为什么它不起作用,但我认为我有一个解决方案:

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

希望这可以帮助!


Jam*_*mes 5

帮助文件中有一条注释lapply:

由于历史原因,lapply创建的调用未被评估,并且编写了依赖于此的代码(例如,bquote).这意味着记录的调用始终为FUN(X [[i]],...)形式,其中i由当前(整数或双精度)索引替换.这通常不是问题,但是如果FUN使用sys.call或match.call,或者它是一个使用该调用的原始函数.这意味着使用包装器调用基本函数通常更安全,因此需要例如lapply(ll,function(x)is.numeric(x))来确保正确地发生is.numeric的方法调度.

lmmatch.call在其开头行中使用两次:

cl <- match.call()
mf <- match.call(expand.dots = FALSE)
Run Code Online (Sandbox Code Playgroud)

帮助文件和@Florian中提到的解决方案是使用匿名函数包装器.

更新

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

...
Run Code Online (Sandbox Code Playgroud)