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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:50:14