survey包中svyglm用na.exclude异常:predict未保留缺失值
survey包svyglm预测时NA值未保留的问题
使用survey包的svyglm拟合模型时,无论是否设置na.action参数,用predict函数生成预测值时,NA值都会被忽略,不像glm的预测结果那样保留NA对应的位置,这给为现有数据框生成新列造成了困扰。
原帖示例代码:
library('survey') y = c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1) x1 = c(1, 0, 1, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 1, 0, 0, 0, 2, 2, 2) x2 = c(10, 21, 33, 55, 40, 30, 26, 84, NA, 87, 20, 21, 23, 25, NA, 60, 76, 84, 71, 87) x3 = runif(20) foo = data.frame(y, x1, x2, x3) m1 = glm(y ~ x1 + x2, family = binomial(logit), na.action = na.exclude) svy1 = svydesign(ids = ~ 0, data = foo, weights = ~ x3) m2 <- svyglm(y ~ x1 + x2, design = svy1, family = binomial(logit), na.action = na.exclude) predict(m1) predict(m2) foo2 = foo foo2$x2 = runif(nrow(foo), 15, 50) foo2$x2[c(8, 15, 19)] = NA predict(m1, newdata = foo2) predict(m2, newdata = foo2)
运行后可见,predict.glm生成的结果包含缺失值,但predict.svyglm的结果里没有对应位置的NA。
问题原因
predict.svyglm的默认na.action参数是na.omit,而且不会继承拟合模型时设置的na.action。哪怕你在拟合svyglm时指定了na.exclude,预测阶段如果不重新指定,它还是会自动删除包含NA的行,导致预测结果长度和原数据不一致。
解决办法
在调用predict.svyglm时,显式指定na.action = na.exclude,就能让预测结果保留NA对应的位置,和glm的行为一致。
修改后的预测代码:
# 保留NA的预测结果 predict(m2, newdata = foo2, na.action = na.exclude)
运行这段代码后,你会得到和predict(m1, newdata = foo2)长度一致的结果,其中对应foo2里x2为NA的位置(第8、15、19行)也会显示NA,这样就能直接添加到数据框里作为新列了。
补充说明
如果遇到特殊情况(比如某些版本的survey包仍有问题),可以手动对齐预测结果和原数据:
- 先获取不处理NA的预测值:
preds <- predict(m2, newdata = foo2, na.action = na.pass) - 然后根据newdata里的NA位置,将对应位置设为NA:
# 找出newdata中模型变量包含NA的行 na_rows <- apply(model.matrix(formula(m2), foo2), 1, function(row) any(is.na(row))) # 插入NA preds[na_rows] <- NA
内容的提问来源于stack exchange,提问作者tcam
相关产品推荐
相关产品推荐

