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

R中read_csv读取大数据集时停滞的原因及解决办法

问题分析与解决方案

为什么程序停滞?是内存不足吗?

是的,内存不足是核心原因。7.9GB内存面对200万行+1300列的数据集,哪怕只筛选部分变量,读取过程中的额外内存开销仍会直接耗尽资源:

  • 多数CSV读取函数会先扫描全量文件推断列类型,这个阶段会占用大量临时内存;
  • 即使指定col_select,read_csv这类函数在类型推断环节仍会将全列数据加载到临时缓存,直到筛选完成才释放;
  • 原始数据集的内存占用远超7.9GB——哪怕每列仅占10KB,1300列的总数据量也会突破13GB,内存打满后系统会启用硬盘虚拟内存,读写速度骤降,表现为程序停滞。

解决方法

1. 精准控制列读取与类型指定

不要仅依赖col_select,提前手动指定列类型,避免自动推断带来的内存浪费:

# 针对所需变量定义类型,数值型用col_double,字符型用col_character,日期用col_date
col_types <- cols_only(
  var_name1 = col_double(),
  var_name2 = col_character(),
  var_name3 = col_date(format = "%Y-%m-%d")
  # 将variables_to_use_2中的所有变量按此格式补充
)
my_data <- read_csv("G:/2005-2019_FinancialData_excl_D&GR_EDIT.csv", 
                    col_select = variables_to_use_2,
                    col_types = col_types)

用fread的话,直接搭配select和colClasses,内存效率更高:

my_data <- fread("G:/2005-2019_FinancialData_excl_D&GR_EDIT.csv",
                 select = variables_to_use_2,
                 colClasses = c(var_name1 = "numeric", var_name2 = "character"))

2. 分块读取数据

若筛选后仍内存不足,将数据集拆分成小块分批读取处理:

chunk_size <- 100000 # 每次读取10万行
total_rows <- 2000000
chunks <- list()

for (i in 0:(total_rows %/% chunk_size)) {
  skip_rows <- i * chunk_size
  # 处理最后一块可能不足chunk_size的情况
  read_rows <- ifelse(skip_rows + chunk_size > total_rows, total_rows - skip_rows, chunk_size)
  chunk <- read_csv("G:/2005-2019_FinancialData_excl_D&GR_EDIT.csv",
                    col_select = variables_to_use_2,
                    col_types = col_types,
                    skip = skip_rows,
                    n_max = read_rows)
  chunks[[i+1]] <- chunk
}

# 若合并后内存足够,再合并所有块;否则直接在单块上处理分析
my_data <- bind_rows(chunks)

3. 优化内存占用

  • 将重复值较多的字符型列转换为因子:
    my_data$var_name2 <- as.factor(my_data$var_name2)
    
  • 使用更高效的数据结构:data.table比普通data.frame内存占用更低,大文件处理性能更优;tibble也略优于原生data.frame。

4. 读取前清理内存

手动释放无用对象,腾出更多空间:

gc() # 强制垃圾回收
rm(list = ls()) # 清空当前环境所有对象,请提前保存需要保留的变量

5. 转换为高效二进制格式(可选)

若需频繁读取该文件,先将CSV转换为fst或feather二进制格式,后续读取速度和内存占用会大幅降低:

library(fst)
# 成功读取一次后保存为fst
write_fst(my_data, "G:/financial_data.fst")
# 后续读取直接调用
my_data <- read_fst("G:/financial_data.fst", columns = variables_to_use_2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:15:15