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

将26万份CSV数据集导入R时电脑冻结,求排查代码问题

批量导入CSV数据集时电脑冻结问题排查

我尝试用以下代码批量导入260,000份CSV格式数据集(单份189KB,总大小46.6GB)到RStudio,代码来自我的研究项目脚本《LASSO code (Version for Antony)》:

# 一次性加载所有必要包
library_list <- c(library(plyr),library(dplyr),library(tidyverse),
                  library(readr),library(stringi),library(purrr),
                  library(stats),library(leaps),library(lars),
                  library(elasticnet),library(data.table),library(parallel),
                  library(microbenchmark))

# 创建数据集文件夹中所有文件的字符列表
folderpath <- "C:/Users/Spencer/Documents/EER Project/datasets folder"
filepaths_list <- list.files(path = folderpath, full.names = TRUE, 
                             recursive = TRUE)
# 重命名CSV数据集
DS_names_list <- basename(filepaths_list)
DS_names_list <- tools::file_path_sans_ext(DS_names_list)

# 对文件名列表进行排序,确保顺序正确
my_order = DS_names_list |> 
  # 拆分数字并转为数值型
  strsplit(split = "-", fixed = TRUE) |>  unlist() |> as.numeric() |>
  # 转为数据框
  matrix(nrow = length(DS_names_list), byrow = TRUE) |> as.data.frame() |>
  # 获取排序规则
  do.call(order, args = _)

DS_names_list = DS_names_list[my_order]
filepaths_list = filepaths_list[my_order]

# 读取所有CSV文件中的数据
CL1 <- makeCluster(detectCores() - 1L)
clusterExport(CL1, c('filepaths_list'))
system.time( datasets <- parLapply(CL1, filepaths_list, fread) )
stopCluster(CL1)

根据之前1000份数据集的测试,预计耗时约36小时,但运行25小时后电脑完全冻结。我的笔记本配置是11代Intel(R) Core(TM) i5-1155G7 @ 2.50GHz处理器、32GB内存、1TB SSD,硬件应该能支撑。此前我用以下代码运行56小时都没冻结:

CL <- makeCluster(detectCores() - 1L)
clusterExport(CL, c('filepaths_list'))
system.time( datasets <- lapply(filepaths_list, read.csv) )

后来发现应该用parLapply(CL, filepaths_list, read.csv)或read_csv就终止了操作。现在想问问上述代码有没有语法错误?


语法错误排查

  • 包加载逻辑错误:library_list <- c(library(plyr),...)写法无效。library()函数返回的是加载成功与否的逻辑值,将这些值存入向量没有实际意义,属于冗余代码。正确的批量加载包方式应该是:
    required_packages <- c("plyr","dplyr","tidyverse","readr","stringi","purrr",
                           "stats","leaps","lars","elasticnet","data.table","parallel","microbenchmark")
    lapply(required_packages, library, character.only = TRUE)
    
  • 并行读取的依赖缺失:使用parLapply调用fread时,未在集群节点加载data.table包。clusterExport仅传递了filepaths_list,但集群节点默认未加载data.table,会导致函数调用失败(你这里表现为冻结而非报错,可能是其他因素叠加,但这是明确的逻辑漏洞)。
  • 排序逻辑的潜在风险:strsplit后直接unlist再转矩阵的写法,仅在所有文件名拆分后元素数量完全一致时有效。如果存在文件名拆分后长度不同的情况,矩阵转换会直接报错。

冻结原因推测(非语法错误但影响稳定性)

  • 内存耗尽:CSV文本读入内存后会膨胀,260,000份数据全部加载会远超过46.6GB,32GB内存被占满后系统会频繁调用虚拟内存,最终导致冻结。单线程read.csv读取时内存增长缓慢,系统有时间处理,而并行读取会快速填满内存。
  • 资源过载竞争:使用detectCores()-1个线程(你的CPU为4核8线程,即7个线程)同时读取文件,磁盘IO成为瓶颈,CPU和内存长时间满负载运行,引发系统不稳定。

优化建议

  1. 修复并行读取逻辑:
    # 正确加载包
    required_packages <- c("plyr","dplyr","tidyverse","readr","stringi","purrr",
                           "stats","leaps","lars","elasticnet","data.table","parallel","microbenchmark")
    lapply(required_packages, library, character.only = TRUE)
    
    # 并行读取时在集群节点加载data.table
    CL1 <- makeCluster(detectCores() - 2L) # 减少线程数降低负载
    clusterExport(CL1, c('filepaths_list'))
    clusterEvalQ(CL1, library(data.table)) # 新增加载依赖
    system.time( datasets <- parLapply(CL1, filepaths_list, fread) )
    stopCluster(CL1)
    
  2. 避免全量加载:如果后续是批量处理而非需要所有数据在内存,采用分批次读取处理的方式,处理完一批后释放对应内存。
  3. 降低并行线程数:比如使用detectCores()/2个线程,减少磁盘IO和CPU竞争,提升系统稳定性。
  4. 实时监控内存:运行时用memory.size()(Windows)或memory_usage()(Linux/macOS)监控内存变化,确认是否因内存耗尽导致冻结。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:00:56