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)
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)
编辑 最终调用是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")
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)
希望这可以帮助!
帮助文件中有一条注释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中提到的解决方案是使用匿名函数包装器.
更新
对于这种改变模型公式的具体问题,你可以重写,以避免调用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
...
Run Code Online (Sandbox Code Playgroud)