在包装函数中调用gamlss predict方法时出现对象未找到错误
GAMLSS模型封装后predict报错的解决办法
问题重现
在封装gamlss基础建模函数用于开发高阶专用包时,调用predict出现object 'input' not found错误,但原生gamlss示例运行正常:
原生示例(正常运行)
suppressMessages(library(gamlss)) data(aids) a <- gamlss(y~poly(x,3)+qrt, family=PO, data=aids) #> GAMLSS-RS iteration 1: Global Deviance = 416.8014 #> GAMLSS-RS iteration 2: Global Deviance = 416.8014 newaids <- data.frame(x=c(45,46,47), qrt=c(2,3,4)) predict(a, newdata = newaids) #> Warning in predict.gamlss(a, newdata = newaids): There is a discrepancy between the original and the re-fit #> used to achieve 'safe' predictions #> #> [1] 6.021313 6.232357 6.155965
封装后代码(报错)
gamlss_fit <- function(input) { gamlss(y~poly(x,3)+qrt, family=PO, data=input) } gamlss_predict <- function(fit, input) { predict(fit, newdata = input) } fit <- gamlss_fit(aids) #> GAMLSS-RS iteration 1: Global Deviance = 416.8014 #> GAMLSS-RS iteration 2: Global Deviance = 416.8014 gamlss_predict(fit, newaids) #> Error in eval(Call$data): object 'input' not found
问题原因
gamlss模型对象会保存拟合时的调用语句(fit$Call)和相关环境。当在gamlss_fit函数内部用data=input拟合时,模型的Call$data是符号input,这个符号仅存在于gamlss_fit的函数环境中。调用predict时,gamlss会尝试在当前执行环境(gamlss_predict的环境或全局环境)查找input,自然找不到,从而抛出错误。
解决办法
方法1:用substitute替换调用中的data参数
修改拟合函数,将调用中的input替换为实际传入的变量名,确保模型调用记录的是真实的数据对象名称:
gamlss_fit <- function(input) { eval(substitute(gamlss(y~poly(x,3)+qrt, family=PO, data=input)), envir = parent.frame()) }
方法2:手动修正模型的调用和环境
直接修改模型对象的Call和terms环境,让predict能正确解析数据来源:
gamlss_fit <- function(input) { fit <- gamlss(y~poly(x,3)+qrt, family=PO, data=input) # 将Call中的data替换为实际传入的对象名称 fit$Call$data <- substitute(input) # 调整terms的环境为父环境,确保变量能被找到 environment(fit$terms) <- parent.frame() fit }
测试修正后的代码
fit <- gamlss_fit(aids) gamlss_predict(fit, newaids) #> Warning in predict.gamlss(fit, newdata = newaids): There is a discrepancy between the original and the re-fit #> used to achieve 'safe' predictions #> #> [1] 6.021313 6.232357 6.155965
内容的提问来源于stack exchange,提问作者Krisrs1128
相关产品推荐
相关产品推荐

