15

我创建了两个广义线性模型,如下所示:

glm1 <-glm(Y ~ X1 + X2 + X3, family=binomial(link=logit))

glm2 <-glm(Y ~ X1 + X2, family=binomial(link=logit))

然后我使用该anova功能:

anova(glm2,glm1)

但收到一条错误消息:

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

这是什么意思,我该如何解决?我attach在代码开头编辑了数据集,因此两个模型都使用同一个数据集。

4

6 回答 6

16

该错误的主要原因是一个或多个预测变量中存在缺失值。在最新版本的 R 中,默认操作是忽略所有缺少任何值的行(以前的默认操作是产生错误)。因此,例如,如果数据框有 100 行并且 X3 中有一个缺失值,那么您的模型 glm1 将适合 99 行数据(删除 X3 缺失的行),但 glm2 对象将适合完整100行数据(由于不使用X3,所以不需要删除任何行)。

那么这个anova函数会给你一个错误,因为这两个模型适合不同的数据集(以及你如何计算自由度等)。

一种解决方案是创建一个新数据框,其中仅包含将在至少一个模型中使用的列,并删除所有缺失值的行(na.omitorna.exclude函数将使这变得容易),然后将两个模型都拟合到没有任何缺失值的相同数据框。

其他选择是查看用于多重插补的工具或其他处理缺失数据的方法。

于 2013-08-22T18:17:23.540 回答
7

为避免该"models were not all fitted to the same size of dataset"错误,您必须在完全相同的数据子集上拟合两个模型。有两种简单的方法可以做到这一点:

  • data=glm1$model在第二个模型中使用
  • data=na.omit(orig.data[ , all.vars(formula(glm1))])或通过在第二个模型拟合中使用来检索正确子集的数据集

这是一个可重复的示例,使用lm(对于glm相同的方法应该有效)和update

# 1st approach
# define a convenience wrapper
update_nested <- function(object, formula., ..., evaluate = TRUE){
    update(object = object, formula. = formula., data = object$model, ..., evaluate = evaluate)
}

# prepare data with NAs
data(mtcars)
for(i in 1:ncol(mtcars)) mtcars[i,i] <- NA

xa <- lm(mpg~cyl+disp, mtcars)
xb <- update_nested(xa, .~.-cyl)
anova(xa, xb)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

# 2nd approach
xc <- update(xa, .~.-cyl, data=na.omit(mtcars[ , all.vars(formula(xa))]))
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     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

也可以看看:

于 2016-05-24T14:20:10.957 回答
1

解决方案是使用:

glm1 <-glm(Y ~ X1 + X2 + X3, family = binomial(link = logit), na.action = na.exclude)
glm2 <-glm(Y ~ X1 + X2, family = binomial(link = logit), na.action = na.exclude)

anova(glm2,glm1)

这将使 R 在拟合模型中包含缺失数据 (NA) 的情况。这确保了数据集在不同拟合模型中是相同的,无论缺失数据如何分布。

于 2015-07-19T01:07:34.183 回答
0

我猜你的意思是输入:

glm1 <-glm(Y ~ X1+X2+X3, family=binomial(link=logit))

glm2 <-glm(Y ~ X1 + X2, family=binomial(link=logit))

R 回归函数的公式接口不将逗号识别为向公式的 RHS 添加协变量。并且不要使用attach(); 使用回归函数的数据参数。

于 2013-08-22T19:01:26.190 回答
0

格雷格·斯诺(Greg Snow)很好地描述了原因。另一种非常简单的解决方案是添加一个新变量,匹配有问题的变量的 NA,否则与值 1 匹配。将它包含在两个模型中,R 将排除两个模型中的相同行(--> 数据集将匹配)。

于 2017-07-03T11:56:31.393 回答
0

我认为在不计算缺失值的情况下处理这种情况的最简单方法是使用 tidyr 的 drop_na() 函数创建一个新数据集。

对于此函数,将最终模型中所需的所有变量放在 drop_na() 部分中,它将删除任何相关变量中缺少值的所有行:

library(tidyr) #load in drop_na()

mtcars[1,2] <- NA #makes the first row of the cyl column become NA to illustrate

no_missing <- mtcars %>%
  drop_na(cyl)

glimpse(no_missing) #note, you only have 31 obs instead of 32 now

drop_na() 也适用于多列:

library(tidyr)

mtcars[1,2] <- NA #makes the first row of the cyl column become NA to illustrate
mtcars[3,1] <- NA #makes the 3rd row of the mpg column become NA to illustrate

no_missing_2 <- mtcars %>%
  drop_na(mpg, cyl)

glimpse(no_missing_2) #now, you only have 30 obs

通过使用您将在最复杂模型中使用的所有变量运行 drop_na(),您将确保使用相同的数据集。

于 2020-01-14T15:39:50.763 回答