在R语言中读取.txt大文件时如何实现随机行抽样?
R超大txt文件读取时随机抽样实现方案
有多种无需全量加载数据的实现方案,适配不同使用场景,具体如下:
方案1:data.table + 系统命令(速度最快,推荐)
借助data.table的fread函数的cmd参数,直接调用系统命令在磁盘层完成抽样后再读取,全程不加载全量数据,5GB文件通常几秒即可完成。
类Unix系统(macOS/Linux/安装了Git Bash的Windows)
library(data.table) # 单个文件抽样,注意替换文件路径和分隔符配置 sample_df <- fread( cmd = "head -n 1 你的文件路径.txt && tail -n +2 你的文件路径.txt | shuf -n 20000", header = TRUE, sep = "\t" # 按实际文件分隔符调整,逗号分隔改为",",空格分隔改为" " )
原生Windows系统(调用PowerShell)
library(data.table) sample_df <- fread( cmd = 'powershell -Command "$header = Get-Content 你的文件路径.txt -Head 1; $content = Get-Content 你的文件路径.txt | Select-Object -Skip 1 | Get-Random -Count 20000; $header + $content"', header = TRUE, sep = "\t" )
方案2:LaF包纯R实现(跨平台,无外部依赖)
如果不想依赖系统命令,可使用专门处理大文本文件的LaF包,纯R环境运行,支持全平台,无需加载全量数据即可按行索引读取。
library(LaF) file_path <- "你的文件路径.txt" # 仅读取文件元信息获取总行数,不加载实际数据 con <- laf_open_delim( filename = file_path, delimiter = "\t", # 按实际调整分隔符 skip = 1 # 跳过表头 ) total_rows <- nrow(con) close(con) # 生成随机抽样行号,跳过表头所在的第一行 sample_rows <- sort(sample(2:total_rows, size = 20000, replace = FALSE)) # 仅读取抽样行 sample_df <- laf_open_delim( filename = file_path, delimiter = "\t", skip = 1 )[sample_rows, ]
方案3:基础R实现(无需安装第三方包)
如果没有权限安装第三方包,可使用基础R的文件连接逐行读取,抽到指定行数后直接终止读取,完全不占用多余内存。
file_path <- "你的文件路径.txt" # 预估抽样概率,按500万行抽2万行设置,可根据实际总行数微调 sample_prob <- 20000 / 5000000 con <- file(file_path, "r") # 读取表头 header <- readLines(con, n = 1) sample_lines <- c(header) # 逐行抽样,抽到20000行即停止读取 while(length(line <- readLines(con, n = 1)) > 0) { if(runif(1) < sample_prob) { sample_lines <- c(sample_lines, line) if(length(sample_lines) >= 20001) break } } close(con) # 转为数据框,按实际调整分隔符 sample_df <- read.delim(text = sample_lines, header = TRUE, sep = "\t")
通用注意事项
- 所有方案中的分隔符参数需根据实际txt文件格式调整,无表头的文件需将
header = TRUE改为FALSE,删除对应的表头跳过配置 - 批量处理2个文件时,只需将文件路径存入向量,遍历执行对应逻辑即可
内容的提问来源于stack exchange,提问作者Jake C
相关产品推荐
相关产品推荐

