使用olsrr包执行逐步回归时遇'data必须为数据框'错误求助
批量使用olsrr包逐步回归的报错解决
需求
用olsrr包的ols_step_backward_aic、ols_step_forward_aic函数,批量处理N个合成数据集,复现stats包step函数(方向分别为'backward'和'forward')的逐步回归结果。
原可运行代码(stats包step函数)
此前用stats包的step函数可正常批量运行:
set.seed(11) # 保证结果可复现 system.time( BE.fits <- parLapply(cl = CL, X = datasets, \(X) { full_models <- lm(X$Y ~ ., X) back <- stats::step(full_models, scope = formula(full_models), direction = 'backward', trace = FALSE) }) ) set.seed(11) # 保证结果可复现 system.time( FS.fits <- parLapply(cl = CL, X = datasets, \(X) { nulls <- lm(X$Y ~ 1, X) full_models <- lm(X$Y ~ ., X) forward <- stats::step(object = nulls, direction = 'forward', scope = formula(full_models), trace = FALSE) }) )
数据集创建代码
datasets是N个同时属于data.table和data.frame类型的列表,创建代码如下:
folderpath <- "C:/Users/Spencer/.../datasets folder" paths_list <- list.files(path = folderpath, full.names = T, recursive = T) datasets <- lapply(paths_list, fread) datasets <- lapply(datasets, function(i) {i[-1:-3, ]}) datasets <- lapply(datasets, \(X) { lapply(X, as.numeric) }) datasets <- lapply(datasets, function(i) { as.data.table(i) })
olsrr包运行报错情况
换成olsrr包函数后无法运行,报错如下:
> set.seed(11) # 保证结果可复现 > BE_fits <- lapply(X = datasets, \(i) { + full_models <- lm(i$Y ~ ., data = i) + backward <- ols_step_backward_aic(full_models) }) Error in eval(model$call$data) : object 'i' not found Called from: eval(model$call$data) Browse[1]> Q
改用seq_along索引后报错:
> BE_fits <- lapply(seq_along(datasets), \(i) { + full_models <- lm(i$Y ~ ., data = i) + backward <- ols_step_backward_aic(full_models) }) Error in model.frame.default(formula = i$Y ~ ., data = i, drop.unused.levels = TRUE) : 'data' must be a data.frame, environment, or list Called from: model.frame.default(formula = i$Y ~ ., data = i, drop.unused.levels = TRUE) Browse[1]> Q
验证信息
- 数据集类型确认:
> class(datasets) [1] "list" > class(datasets[[5]]) [1] "data.table" "data.frame"
- 单个数据集单独执行可正常运行:
full <- lm(datasets[[5]]$Y ~ ., data = datasets[[5]]) backward_elimination <- ols_step_backward_aic(full)
已尝试的无效方法
- 手动输入所有自变量,仍报相同错误;
- 将数据集转为data.frame,错误依旧;
- 在lm中显式转为
as.data.frame,出现“$ operator is invalid for atomic vectors”错误; - 使用
datasets[[i]]索引,报错“object 'i' not found”。
解决方案
问题根源在于olsrr包的函数会尝试从lm模型的调用环境中直接查找数据集对象,但lapply的迭代变量仅存在于临时环境中,olsrr无法识别。以下是两种有效解决方法:
方法1:使用with()创建lm模型
通过with()将数据集的环境绑定到lm调用中,让olsrr能正确获取数据:
set.seed(11) BE_fits <- lapply(datasets, \(dt) { full_model <- with(dt, lm(Y ~ .)) ols_step_backward_aic(full_model) })
方法2:显式将数据集赋值到当前环境
把迭代的数据集赋值给一个新变量,让olsrr能在环境中找到该对象:
set.seed(11) BE_fits <- lapply(datasets, \(dt) { current_data <- dt full_model <- lm(Y ~ ., data = current_data) ols_step_backward_aic(full_model) })
前向逐步回归适配代码
按同样逻辑修改前向逐步回归代码:
set.seed(11) FS_fits <- lapply(datasets, \(dt) { current_data <- dt null_model <- lm(Y ~ 1, data = current_data) full_model <- lm(Y ~ ., data = current_data) ols_step_forward_aic(null_model, scope = formula(full_model)) })
并行处理版本(适配parLapply)
如果需要并行处理,调整代码确保子进程能正确获取数据:
set.seed(11) system.time( BE.fits <- parLapply(cl = CL, X = datasets, \(dt) { current_data <- dt full_model <- lm(Y ~ ., data = current_data) ols_step_backward_aic(full_model) }) )
内容的提问来源于stack exchange,提问作者Marlen
相关产品推荐
相关产品推荐

