使用mutate调用predict.gam出现NA/NaN/Inf报错的问题求助
问题根因
- 你在
ifelse分支中调用预测函数时,R会先完整计算两个分支的所有结果再按条件筛选,即便你设置了!var3 == 0的过滤条件,预测逻辑还是会把for_est全量数据代入计算,只要存在1条var3 <= 0的记录,log(var3)就会生成Inf/NaN值触发报错。 - 你将GAM模型训练逻辑嵌套在
mutate内,既会导致模型被重复训练、运行效率极低,同时如果训练集for_model中存在var3 <= 0的记录,训练阶段就会生成无效值直接报错。 - ggplot的
geom_smooth默认会自动丢弃拟合过程中产生的缺失值、无穷值,因此不会触发报错,和手动调用gam的默认行为存在差异。 var2可正常运行的原因是训练集、预测集中的var2均不存在<=0的记录,log计算不会生成无效值。
解决方案
第一步:提前预处理训练数据,单独训练GAM模型,避免训练阶段出现无效值:
library(mgcv) library(dplyr) # 过滤训练集中var3<=0的观测,避免log计算生成Inf/NaN train_clean <- for_model %>% filter(var3 > 0) # 单独训练模型,设置自动忽略剩余缺失值 gam_mod <- gam(var4 ~ s(log(var3)), data = train_clean, na.action = na.omit)
第二步:预测时先过滤符合条件的观测,再赋值预测结果,避免全量计算:
for_est <- for_est %>% # 先初始化var4为NA mutate(var4 = NA_real_) %>% # 仅对var3>0的行做预测 rows_update( y = filter(., var3 > 0) %>% mutate(var4 = predict.gam(gam_mod, newdata = .)), by = intersect(names(.), names(for_est)) )
如果你的dplyr版本较低不支持rows_update,可以用以下替代写法:
valid_idx <- which(for_est$var3 > 0) for_est$var4[valid_idx] <- predict.gam(gam_mod, newdata = for_est[valid_idx, ])
内容的提问来源于stack exchange,提问作者Fred-LM
相关产品推荐
相关产品推荐

