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

为何train()函数在for循环中无法运行?出现未定义列选择错误

解决caret::train()在for循环中报错及拟合指标图异常的问题

Hey,我来帮你搞定这个问题!你碰到的两个问题——循环报错和ggplot出直线,根源其实是同一个:公式里的循环变量d没有被正确解析。

先复现下你的问题场景:
你运行这段多项式回归调参代码时:

library(ISLR)
attach(Wage)
library(caret)
set.seed(1)
inTraining = createDataPartition(Wage$age, p = .75, list = FALSE)
training = Wage[ inTraining,]
testing = Wage[-inTraining,]
fitControl <- trainControl(## 10-fold CV
  method = "repeatedcv",
  number = 10,
  repeats = 10)
set.seed(2)
degree = 1:10
RSquared = rep(0,10)
RMSE = rep(0,10)
for ( d in degree) {
  LinearRegressor <- train(wage ~ poly(age,d),data=training, method = "lm", trControl = fitControl)
  RSquared[d] <- LinearRegressor$results$Rsquared
  RMSE[d]<- LinearRegressor$results$RMSE
}
library(ggplot2)
Degree.RegParams = data.frame(degree,RSquared,RMSE)
ggplot(aes(x = degree,y = RSquared),data = Degree.RegParams) + geom_line()
ggplot(aes(x = degree,y = RMSE),data = Degree.RegParams) + geom_line()

会弹出错误:

Error in `[.data.frame`(data, , all.vars(Terms), drop = FALSE) : undefined columns selected

而且最后画出来的R²和RMSE图都是直线,这是因为train()根本没正常完成拟合,RSquared和RMSE一直是初始的0值。

问题原因

当你在train()的公式里写poly(age,d)时,caret的公式解析器会把d当成training数据框里的列名来查找,但你的Wage数据里根本没有叫d的列,所以就会报“未定义列”的错误。同时,拟合过程异常中断,导致你记录的RSquared和RMSE都是初始的0,自然画出来是直线。

解决方案

我们需要动态生成公式,让循环变量d被解析成当前的数值,而不是列名。这里有两种简单的实现方式:

方式1:用reformulate()创建动态公式

for ( d in degree) {
  # 动态构建公式:wage ~ poly(age, 当前d值)
  fit_formula <- reformulate(paste0("poly(age, ", d, ")"), response = "wage")
  LinearRegressor <- train(fit_formula, data=training, method = "lm", trControl = fitControl)
  RSquared[d] <- LinearRegressor$results$Rsquared
  RMSE[d]<- LinearRegressor$results$RMSE
}

方式2:拼接字符串后转成公式

for ( d in degree) {
  # 先把公式拼成字符串,再转成formula对象
  formula_str <- paste0("wage ~ poly(age, ", d, ")")
  LinearRegressor <- train(as.formula(formula_str), data=training, method = "lm", trControl = fitControl)
  RSquared[d] <- LinearRegressor$results$Rsquared
  RMSE[d]<- LinearRegressor$results$RMSE
}

验证效果

修复后重新运行代码,循环不会再报错,RSquared和RMSE会正确记录每个多项式阶数的交叉验证结果,最后用ggplot画出来的图会是符合预期的曲线(比如R²随阶数上升先提升后趋于平稳,RMSE先下降后平稳)。

内容的提问来源于stack exchange,提问作者nicholas heimpel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:42:46