如何在相同的数据子集上更新`lm`或`glm`模型?

时间:2014-03-15 20:06:37

标签: r regression glm lm

我正在尝试拟合两个嵌套模型,然后使用anova函数对彼此进行测试。使用的命令是:

probit <- glm(grad ~ afqt1 + fhgc + mhgc + hisp + black + male, data=dt, 
    family=binomial(link = "probit"))
nprobit <- update(probit, . ~ . - afqt1)
anova(nprobit, probit, test="Rao")

但是,变量afqt1显然包含NA,因为update调用不会使用相同的数据子集,anova()会返回错误

  

anova.glmlist中的错误(c(list(object),dotargs),dispersion = dispersion,:     模型并非都适合相同大小的数据集

是否有一种简单的方法可以在与原始模型相同的数据集上实现模型的重新设计?

1 个答案:

答案 0 :(得分:1)

正如评论中所建议的那样,直接的方法是使用来自第一个拟合的model数据(例如probit)和update来覆盖来自原来的电话。

这是一个可重复的例子:

data(mtcars)
mtcars[1,2] <- NA
nobs( xa <- lm(mpg~cyl+disp, mtcars) ) 
## [1] 31
nobs( update(xa, .~.-cyl) )  ##not nested
## [1] 32
nobs( xb <- update(xa, .~.-cyl, data=xa$model) )  ##nested
## [1] 31

很容易定义一个方便的包装器:

update_nested <- function(object, formula., ..., evaluate = TRUE){
    update(object = object, formula. = formula., data = object$model, ..., evaluate = evaluate)
}

这会强制更新调用的data参数重新使用第一个模型拟合中的数据。

nobs( xc <- update_nested(xa, .~.-cyl) )
## [1] 31
all.equal(xb, xc)  ##only the `call` component will be different
## [1] "Component “call”: target, current do not match when deparsed"
identical(xb[-10], xc[-10])
## [1] TRUE

现在您可以轻松地执行anova

anova(xa, xc)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     28 269.97                              
## 2     29 312.96 -1   -42.988 4.4584 0.04378 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

建议的另一种方法是在na.omit调用之前的数据框上lm()。起初我认为在处理大数据帧(例如1000列)和各种规格中的大量变量(例如~15变量)时这是不切实际的,但不是因为速度。这种方法需要手动记录哪些变量应该对NA进行消毒,哪些不应该,并且正是OP似乎有意避免的。最大的缺点是您必须始终将formula与子集化数据帧保持同步。

然而,事实证明,这可以很容易地克服:

data(mtcars)
for(i in 1:ncol(mtcars)) mtcars[i,i] <- NA
nobs( xa <- lm(mpg~cyl + disp + hp + drat + wt + qsec + vs + am + gear + 
                    carb, mtcars) ) 
## [1] 21
nobs( xb <- update(xa, .~.-cyl) )  ##not nested
## [1] 22
nobs( xb <- update_nested(xa, .~.-cyl) )  ##nested
## [1] 21
nobs( xc <- update(xa, .~.-cyl, data=na.omit(mtcars[ , all.vars(formula(xa))])) )  ##nested
## [1] 21
all.equal(xb, xc)
## [1] "Component “call”: target, current do not match when deparsed"
identical(xb[-10], xc[-10])
## [1] TRUE

anova(xa, xc)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp + hp + drat + wt + qsec + vs + am + gear + carb
## Model 2: mpg ~ disp + hp + drat + wt + qsec + vs + am + gear + carb
##   Res.Df    RSS Df Sum of Sq      F Pr(>F)
## 1     10 104.08                           
## 2     11 104.42 -1  -0.34511 0.0332 0.8591