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

predict.lme无法识别函数内变量定义的公式问题求助

解决predict.lme无法识别嵌套函数中动态定义公式的问题

问题根源

你遇到的错误是因为lme模型对象会保留拟合时的调用表达式(fit@call$fixed存储的是变量名fixForm而非实际公式),而predict.lme在执行时,会尝试在当前环境中查找fixForm变量。由于fixForm是train_test_perf函数的局部变量,函数执行完毕后局部环境被销毁,导致predict无法找到该变量。

解决方案(保留嵌套函数结构)

以下两种方法都能解决问题,且无需改变你的嵌套函数架构:

方法1:修改模型调用中的fixed参数为实际公式

拟合模型后,手动将模型对象的call$fixed替换为实际的公式对象,这样predict时会直接使用公式而非查找变量:

train_test_perf <- function(train_data, test_data, model, termLabels) {
  fixForm <- reformulate(termlabels=termLabels, response="Y")
  fit <- nlme::lme(fixForm, data=train_data, random=~ 1|ID)
  # 关键:将模型调用中的fixed参数替换为实际公式
  fit@call$fixed <- fixForm
  train_pred <- predict(fit, newdata=train_data, level=0, na.action=na.exclude)
  rtrain <- cor.test(train_data$Y, train_pred)
  test_pred <- predict(fit, newdata=test_data, level=0, na.action=na.exclude)
  rtest <- cor.test(test_data$Y, test_pred)
  tmp <- data.frame(Model=model, 
                    R_train=rtrain$estimate, 
                    R_test=rtest$estimate)
  return(tmp)
}

# 外层函数和调用保持不变
myfunc <- function(df, newdf, varList) {
  for (v in varList) {
    perf <- train_test_perf(train_data=df, test_data=newdf, model=v, termLabels=v)
    print(perf)
  }
}

myfunc(df=dat, newdf=newdat, varList=list("W", "X"))

方法2:直接创建带全局环境的公式

跳过reformulate,直接用字符拼接生成公式,并显式指定公式的环境为全局环境,避免predict时的环境查找问题:

train_test_perf <- function(train_data, test_data, model, termLabels) {
  # 直接拼接公式字符串并解析,指定环境为全局
  fixForm <- as.formula(paste("Y ~", paste(termLabels, collapse=" + ")), env = .GlobalEnv)
  fit <- nlme::lme(fixForm, data=train_data, random=~ 1|ID)
  train_pred <- predict(fit, newdata=train_data, level=0, na.action=na.exclude)
  rtrain <- cor.test(train_data$Y, train_pred)
  test_pred <- predict(fit, newdata=test_data, level=0, na.action=na.exclude)
  rtest <- cor.test(test_data$Y, test_pred)
  tmp <- data.frame(Model=model, 
                    R_train=rtrain$estimate, 
                    R_test=rtest$estimate)
  return(tmp)
}

方法对比

  • 方法1更稳妥:保留了公式的原始环境,适合包含复杂变量或局部对象的场景。
  • 方法2更简洁:适合变量均存在于数据或全局环境的简单场景。

内容的提问来源于stack exchange,提问作者Jeff Phillips

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:02:57