我尝试编写一个包装函数来批量进行似然比检验。我尝试包含update()来更新初始模型。但是,它似乎不是在函数内部查找对象,而是在全局环境中搜索对象。
fake <- data.frame(subj= rep(1:5, 4),
factor1 = rep(LETTERS[c(1,2,1,2)], each=5),
factor2 = rep(letters[1:2], each=10),
data=sort(rlnorm(20)))
foo <- function(){
temp <- fake
model1 <- lmer(data~factor1*factor2 + (1 |subj), temp)
model1a <- update(model1, ~.-factor1:factor2)
model1a}
它在下面给出了错误消息:
Error in eval(expr, envir, enclos) : object 'factor1' not found
无论如何在函数内进行update()搜索?谢谢!
编辑:
我犯了一个错误。我想把“temp”传给lmer而不是“假”。EDIT2: 建议的一个方便的解决方案是简单地指定数据对象。虽然update()现在没有问题,但anova()似乎认为我想要比较的模型是基于不同的数据对象
foo <- function(){
temp <- fake
model1 <- lmer(data~factor1*factor2 + (1 |subj), data=temp)
model1a <- update(model1, ~.-factor1:factor2, data=temp)
anova(model1, model1a)
}
foo()
我收到错误消息:
Error in anova(model1, model1b) :
all models must be fit to the same data object
我认为这个错误超出了update()。但我想知道是否有人知道如何解决这个问题。请注意,如果我在不使用update()的情况下编写函数,而是拼出模型(见下文),则上面的错误就会消失:
foo <- function(){
temp <- fake
model1 <- lmer(data~factor1*factor2 + (1 |subj), data=temp)
model1a <- lmer(data~factor1 + factor2 + (1 |subj), data=temp)
anova(model1, model1a)
}
foo()
Data: temp
Models:
model1a: data ~ factor1 + factor2 + (1 | subj)
model1: data ~ factor1 * factor2 + (1 | subj)
Df AIC BIC logLik Chisq Chi Df Pr(>Chisq)
model1a 5 -4.6909 3.7535 7.3454
model1 6 -8.8005 1.3327 10.4003 6.1097 1 0.01344 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
编辑3: 似乎问题出在anova()上。我也试过了@hadley的建议
foo2 <- function(){
my_update <- function(mod, formula = NULL, data = NULL) {
call <- getCall(mod)
if (is.null(call)) {
stop("Model object does not support updating (no call)", call. = FALSE)
}
term <- terms(mod)
if (is.null(term)) {
stop("Model object does not support updating (no terms)", call. = FALSE)
}
if (!is.null(data)) call$data <- data
if (!is.null(formula)) call$formula <- update.formula(call$formula, formula)
env <- attr(term, ".Environment")
eval(call, env, parent.frame())}
model1 <- lmer(data~factor1*factor2 + (1 |subj), temp)
model1a <- my_update(model1, ~.-factor1:factor2)
anova(model1, model1a)
}
foo2()
我收到如下所示的错误消息:
Error in as.data.frame.default(data) :
cannot coerce class 'structure("mer", package = "lme4")' into a data.frame
答案 0 :(得分:9)
我之前也被这种行为所困扰,所以我写了我自己的update
版本。它评估公式环境中的所有内容,因此它应该相当健壮。
my_update <- function(mod, formula = NULL, data = NULL) {
call <- getCall(mod)
if (is.null(call)) {
stop("Model object does not support updating (no call)", call. = FALSE)
}
term <- terms(mod)
if (is.null(term)) {
stop("Model object does not support updating (no terms)", call. = FALSE)
}
if (!is.null(data)) call$data <- data
if (!is.null(formula)) call$formula <- update.formula(call$formula, formula)
env <- attr(term, ".Environment")
eval(call, env, parent.frame())
}
library(nlme4)
fake <- data.frame(
subj = rep(1:5, 4),
factor1 = rep(LETTERS[c(1,2,1,2)], each = 5),
factor2 = rep(letters[1:2], each = 10),
data = sort(rlnorm(20)))
foo <- function() {
temp <- fake
model1 <- lmer(data ~ factor1 * factor2 + (1 | subj), fake)
model1a <- my_update(model1, ~ . - factor1:factor2)
model1a
}
foo()
答案 1 :(得分:4)
虽然我非常喜欢@Hadley的答案(并且可能会自己使用该功能),但您也可以在data
函数中指定update
参数。 (在这里,我假设您想将temp
传递给您的模型。)
model1a <- update(model1, ~.-factor1:factor2, data = temp)
修改强>
如果您希望将模型与anova
进行比较,update
会将data
参数的名称和“技巧”anova
混为一谈,相信这两个模型使用两个不同的数据集拟合模型。仅更新公式并创建新模型将避免这种情况:
foo <- function(){
temp <- fake
model1 <- lmer(data~factor1*factor2 + (1 |subj), data=temp)
newForm <- update.formula(formula(model1), ~.-factor1:factor2)
model1a <- lmer(newForm, data=temp)
anova(model1, model1a)
}