【问题标题】:How to update `lm` or `glm` model on same subset of data?如何在同一数据子集上更新“lm”或“glm”模型?
【发布时间】:2014-04-21 04:02:10
【问题描述】:

我正在尝试拟合两个嵌套模型,然后使用 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 显然包含NAs,并且因为update 调用不采用相同的数据子集,anova() 返回错误

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

有没有一种简单的方法可以实现在与原始模型相同的数据集上重新拟合模型?

【问题讨论】:

  • 使用所有这些协变量创建数据子集并使用na.omit
  • 如果你做“小规模”分析当然是可能的,但是如果你想拟合和测试多个规范并且你的数据集可以包含许多协变量,那将是相当乏味的,这就是为什么我我要求“更简单”的方式。 (类似于update???中的选项)
  • na.actionglm 然后
  • @landroni 如果您的完整模型是 mtcars[1:5]data &lt;- na.omit(mtcars[1:5]) 删除所有具有任何 NA 值的行,以便您可以使用所有模型上的数据来确保它们适合相同大小的数据.或者xa$model 包含您的 31 个观察数据
  • @landroni nobs( update(xa, .~.-cyl, data = xa$model) ) ?刚刚在 100,000x1,000 数据帧上尝试了 na.omit,它几乎是即时的,所以我真的不知道你所说的不切实际、手动记账或不满意是什么意思

标签: r regression glm lm


【解决方案1】:

正如 cmets 中所建议的,一种直接的方法是使用第一次拟合的 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.omitlm() 调用之前的数据帧上。起初,我认为这在处理大数据帧(例如 1000 列)和各种规格的大量变量(例如 ~15 个变量)时是不切实际的,但不是因为速度。这种方法需要手动记账哪些 vars 应该对 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多