You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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包仍有问题),可以手动对齐预测结果和原数据:

  1. 先获取不处理NA的预测值:preds <- predict(m2, newdata = foo2, na.action = na.pass)
  2. 然后根据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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:33:30