R语言for循环报错:下标越界及optim.spar返回异常值求助
R语言代码修复:下标越界与最优spar值异常问题
问题概述
- 初始报错:
Error in data1[, "Ages"] : subscript out of bounds,修正拼写错误(将"Ages"改为"Age")后,出现新问题:预期optim.spar返回单个十进制值(如0.372),但实际返回包含4个数字的列表[[1]] [1] 15 25 55 85。
代码问题分析与修复方案
核心问题点
- 未定义
training和validation对象,直接调用会导致运行报错 - 不必要用列表存储
sm.spar,hyper_param_spars$spar本身是向量,直接取值即可 optim.spar变量名错误,原代码写为hyper_param,实际应为hyper_param_spars- 平滑样条拟合后直接用
fitted()无法匹配验证集数据,需用predict()针对验证集年龄做预测
修复后的完整代码
library(demography) library(splines) # 读取日本死亡率数据(替换为你的HMD账号密码) JPNmort <- hmd.mx("JPN","username","password") age = 2:110 # 构建2016、2017年数据 data1 <- cbind(1:109, JPNmort[["rate"]][["total"]][age, "2016"], JPNmort[["pop"]][["total"]][age, "2016"]) data2 <- cbind(1:109, JPNmort[["rate"]][["total"]][age, "2017"], JPNmort[["pop"]][["total"]][age, "2017"]) # 设置列名与行名 column.names <- c("Age", "mu_x", "Ec_x") colnames(data1) <- column.names colnames(data2) <- column.names rownames(data1) <- NULL rownames(data2) <- NULL # 划分训练集与验证集(示例:2016为训练,2017为验证) training <- data1 validation <- data2 # 生成spar候选值 spars.values <- seq(from = 0, to = 1, by = 0.001) hyper_param_spars <- data.frame(spar = spars.values, Error.Rate = 0) # 存储样条模型 sm.spline <- vector("list", nrow(hyper_param_spars)) # 遍历候选spar值计算MSE for(i in 1:nrow(hyper_param_spars)) { current_spar <- hyper_param_spars$spar[i] # 拟合训练集 sm.spline[[i]] <- smooth.spline(training$Age, training$mu_x, spar = current_spar) # 预测验证集并计算MSE pred_mu <- predict(sm.spline[[i]], x = validation$Age)$y hyper_param_spars$Error.Rate[i] <- mean((validation$mu_x - pred_mu)^2) } # 获取最优spar值 optim.spar <- hyper_param_spars$spar[which.min(hyper_param_spars$Error.Rate)]
关键修复说明
- 明确划分训练/验证集:将2016年数据作为训练集,2017年作为验证集,可根据需求调整划分逻辑
- 简化spar取值:直接从
hyper_param_spars$spar取单个值,避免不必要的列表存储 - 正确计算验证集误差:用
predict()针对验证集年龄生成预测值,确保MSE计算的是验证集的真实误差 - 修正变量名:将
hyper_param改为hyper_param_spars,避免对象不存在的错误
内容的提问来源于stack exchange,提问作者Ngan DO
相关产品推荐
相关产品推荐

