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

如何在R中合并757个总计57.4GB的CSV文件且避免内存溢出?

大体积CSV文件合并的内存优化与问题排查

问题描述

我共有757个单文件约80MB、总计57.4GB的CSV格式数据,希望将所有文件合并为单个文件。用于小样本(52个文件)的如下代码可正常运行:

# Reading in multiple files of genetic data at once
setwd()
files = list.files(pattern = "*.csv")
gene1 <- do.call(rbind, lapply(files, fread))
rm(files)

gene1 <- as.data.frame(unclass(gene1))

但处理全部文件时,RStudio运行数分钟后崩溃。我猜测是内存问题,想了解是否有避免内存占满的方法(了解Python有分块处理选项),也请告知是否存在其他可能问题。

内存优化方案(避免内存占满)

1. 逐文件追加写入(核心推荐)

全程仅加载单个文件到内存,读取后直接追加到输出文件,不累积全量数据,内存占用仅取决于单个CSV的大小:

library(data.table)
# 设置输出文件路径
output_path <- "merged_all.csv"
# 获取所有目标CSV文件
csv_files <- list.files(pattern = "*.csv")

# 处理第一个文件(写入表头+数据,覆盖已有文件)
first_dt <- fread(csv_files[1])
fwrite(first_dt, output_path)
rm(first_dt)
gc() # 强制垃圾回收释放内存

# 循环处理剩余文件,追加写入
for (file in csv_files[-1]) {
  current_dt <- fread(file)
  fwrite(current_dt, output_path, append = TRUE)
  rm(current_dt)
  gc() # 每次循环后清理内存
}

2. 单文件分块读取(针对单个文件也偏大的场景)

如果单个80MB文件仍对内存有压力,可以把单个文件拆分成小块读取,再逐块追加:

library(data.table)
output_path <- "merged_all.csv"
csv_files <- list.files(pattern = "*.csv")

# 先写入表头(从第一个文件提取)
header_dt <- fread(csv_files[1], nrows = 0)
fwrite(header_dt, output_path)

for (file in csv_files) {
  # 获取当前文件总行数
  total_rows <- fread(file, select = 1, nrows = -1)[, .N]
  chunk_size <- 100000 # 每次读取10万行,可根据内存情况调整
  
  # 分块读取并追加
  for (start_row in seq(1, total_rows, chunk_size)) {
    # 第一块跳过表头,后续块直接从指定行开始读
    skip_lines <- ifelse(start_row == 1, 1, start_row)
    chunk_dt <- fread(file, skip = skip_lines, nrows = chunk_size)
    fwrite(chunk_dt, output_path, append = TRUE)
    rm(chunk_dt)
    gc()
  }
}

3. 转换为高效存储格式后合并

如果后续需要用R频繁处理数据,可以先将CSV转成fst/parquet这类高压缩、低内存的格式,再合并:

library(data.table)
library(fst)

# 批量将CSV转为fst格式
csv_files <- list.files(pattern = "*.csv")
for (file in csv_files) {
  dt <- fread(file)
  fst_path <- gsub(".csv", ".fst", file)
  write_fst(dt, fst_path, compress = 100) # 最高压缩率
  rm(dt)
  gc()
}

# 合并fst文件
fst_files <- list.files(pattern = "*.fst")
output_fst <- "merged_all.fst"

# 写入第一个fst文件
first_fst <- read_fst(fst_files[1])
write_fst(first_fst, output_fst)
rm(first_fst)
gc()

# 追加剩余fst文件
for (file in fst_files[-1]) {
  current_fst <- read_fst(file)
  write_fst(current_fst, output_fst, append = TRUE)
  rm(current_fst)
  gc()
}

# 若需要最终输出CSV,再转换
final_dt <- read_fst(output_fst)
fwrite(final_dt, "merged_all.csv")

其他可能导致崩溃的问题

  • 文件格式不一致:部分CSV可能存在列数不匹配、表头差异、数据类型冲突(比如同一列在甲文件是字符,乙文件是数值),rbind时会触发内存异常。可提前批量检查:
    csv_files <- list.files(pattern = "*.csv")
    # 检查列数一致性
    col_counts <- sapply(csv_files, function(x) ncol(fread(x, nrows = 1)))
    if (length(unique(col_counts)) > 1) {
      problematic <- names(col_counts[col_counts != unique(col_counts)[1]])
      stop("列数不一致的文件:", paste(problematic, collapse = ", "))
    }
    # 检查表头一致性
    headers <- sapply(csv_files, function(x) paste(names(fread(x, nrows = 0)), collapse = ","))
    if (length(unique(headers)) > 1) {
      problematic <- names(headers[headers != unique(headers)[1]])
      stop("表头不一致的文件:", paste(problematic, collapse = ", "))
    }
    
  • 磁盘空间不足:合并后的CSV体积接近甚至超过57.4GB,若目标磁盘剩余空间不足,会导致写入失败进而崩溃,先确认磁盘可用空间。
  • RStudio内存限制:RStudio默认有内存使用上限,可通过工具 → 全局选项 → 常规 → 内存限制调整,但这只是临时方案,核心还是优化读取逻辑。
  • 系统资源竞争:运行时其他程序占用大量内存/CPU,导致RStudio无法获取足够资源,关闭不必要程序后再尝试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:25:27