我有一个庞大的(8GB)数据集,我根本无法使用现有设置读入R。尝试在数据集上使用fread
会立即崩溃R会话,并且尝试从基础文件中读取随机行是不够的,因为:(1)我没有很好的方法知道总行数在数据集中; (2)我的方法不是真正的“随机抽样”。
这些获取行数的尝试都失败了(只需简单地读取数据就可以了:
length(count.fields("file.dat", sep = "|"))
read.csv.sql("file.dat", header = FALSE, sep = "|", sql = "select
count(*) from file")
有没有办法通过R或其他程序从大型底层数据集中生成随机样本?
潜在的想法:有可能,给出前几行的“样本”,以了解每行所包含的平均信息量。然后根据数据集的大小(8 GB)退出必须有多少行?这可能不准确,但它可能会给我一个球场公园的数字,我可能只是削减不足。
答案 0 :(得分:3)
这是一个选项,使用fread
接受shell命令预处理文件作为输入的能力。使用此选项,我们可以运行gawk
脚本来提取所需的行。请注意,如果您的系统上尚未安装gawk,则可能需要安装gawk。如果您的系统上有awk
,则可以改用它。
首先让我们创建一个虚拟文件来测试:
library(data.table)
dt = data.table(1:1e6, sample(letters, 1e6, replace = TRUE))
write.csv(dt, 'test.csv', row.names = FALSE)
现在我们可以使用shell命令wc
来查找文件中有多少行:
nl = read.table(pipe("wc -l test.csv"))[[1]]
获取行号的样本并将它们(按升序排列)写入临时文件,这样可以轻松访问它们。
N = 20 # number of lines to sample
sample.lines = sort(sample(2:nl, N)) #start sample at line 2 to exclude header
cat(paste0(sample.lines, collapse = '\n'), file = "lines.txt")
现在,我们已准备好使用fread
和gawk
(基于this answer)阅读示例。您还可以尝试这个链接问题中的一些其他gawk脚本,这些脚本可能在非常大的数据上更有效。
dt.sample = fread("gawk 'NR == FNR {nums[$1]; next} FNR in nums' lines.txt test.csv")