update() 不适用于通过 lapply() 创建的模型

update() does not work for models created via lapply()

我想使用 lapply() 在 R 中计算多个模型,但 update() 函数似乎无法处理通过 lapply() 生成的模型。

一个最小的例子:

d1 <- data.frame(y = log(1:9), x = 1:9, trt = rep(1:3, each = 3))

f <- list(y ~ 1, y ~ x, y ~ trt)

modsa <- lapply(f, function(formula) glm(formula, data = d1))
modsb <- lapply(f, glm, data = d1)

update(modsa[[1]], data = d1[1:7, ])
#> Error: object of type 'closure' is not subsettable
update(modsb[[1]], data = d1[1:7, ])
#> Error in FUN(formula = X[[i]], data = d1[1:7, ]): could not find function "FUN"

有没有办法让 update() 处理通过 lapply() 生成的模型?

发生错误是因为 glm 对象的 call 元素被传递给匿名函数的参数名称覆盖

modsa <- lapply(f, function(x) glm(x, data = d1))

modsa[[1]]$call
 glm(formula = x, data = d1)

#compare with a single instance of the model    
moda1<-glm(y ~ 1, data=d1)

moda1$call
 glm(formula = y ~ 1, data = d1)

如果您在公式中重新添加,它将正确地重新创建调用

update(modsa[[1]], data = d1[1:7, ], formula=f[[1]])

这对第二个实例不起作用,但您可以看到,如果您手动更新调用元素,更新功能就会恢复。

modsb[[1]]$call<-getCall(moda1)

update(modsb[[1]], data = d1[1:7, ])

Esther 是正确的,问题出在glm 的call 元素上。来自 ?update:

‘update’ will update and (by default) re-fit a model. It does this by extracting the call stored in the object, updating the call and (by default) evaluating that call.

如前所述,也可以更新包括公式:

update(modsa[[1]], data = d1[1:7, ], formula=f[[1]])

如果由于某种原因这不方便,这里是如何 运行 您的 lapply() 并让它直接将正确的公式分配给调用元素:

modsa <- lapply(f, function(formula) eval(substitute(glm(F, data = d1), list(F=formula))))

这会将相应的公式替换为 glm 调用,然后对其求值。有了这个长单行,您可以 运行 update(modsa[[1]], data = d1[1:7, ]) 毫无问题。