R:大规模数据帧的简单随机样本

R:大规模数据帧的简单随机样本,r,statistics,R,Statistics,我有一个巨大的(8GB)数据集,我无法使用现有设置将其读入R。试图在数据集上使用fread会立即导致R会话崩溃,并且试图从基础文件中随机读取行是不够的,因为:(1)我没有很好的方法知道数据集中的行总数;(2) 我的方法不是真正的“随机抽样” 这些获取行数的尝试失败(只需在以下位置读取数据即可: 长度(count.fields(“file.dat”,sep=“|”) read.csv.sql(“file.dat”,header=FALSE,sep=“|”,sql=“选择 计数(*)来自文件“ 有没

我有一个巨大的(8GB)数据集,我无法使用现有设置将其读入R。试图在数据集上使用
fread
会立即导致R会话崩溃,并且试图从基础文件中随机读取行是不够的,因为:(1)我没有很好的方法知道数据集中的行总数;(2) 我的方法不是真正的“随机抽样”

这些获取行数的尝试失败(只需在以下位置读取数据即可:

  • 长度(count.fields(“file.dat”,sep=“|”)
  • read.csv.sql(“file.dat”,header=FALSE,sep=“|”,sql=“选择
    计数(*)来自文件“
  • 有没有办法通过R或其他程序从大型基础数据集生成随机样本


    潜在想法:有没有可能,给定前几行的“样本”,以了解每行所包含的平均信息量。然后返回给定数据集大小(8GB)的行数?这可能不准确,但它可能会给出一个大概的数字,我可以略低于这个数字。

    这里有一个选项,使用
    fread
    的功能接受一个shell命令,该命令将预处理文件作为其输入。使用此选项,我们可以运行
    gawk
    脚本来提取所需的行。注意,您可能需要安装ga如果您的系统上还没有awk,则可以使用它。如果您的系统上有
    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
    (基于)阅读示例。您还可以尝试此链接问题中的其他一些gawk脚本,它们可能在非常大的数据上更有效

    dt.sample = fread("gawk 'NR == FNR {nums[$1]; next} FNR in nums' lines.txt test.csv")
    

    将它放在SQLite数据库中,直接通过RSQLite或通过dplyr获取一组随机行。有类似的方法,但我不知道在普通R包中有任何实现。读取第一列以获得行数(使用
    列名
    )。然后使用
    fread
    函数的
    skip
    nrow
    参数分块读取。从未测试过它,但它可能会工作,尽管它可能会非常慢。每次获取块时,从中获取一个样本,并
    rm
    它。包含有关在不读取fil的情况下获取行计数的信息e、 如果您获得行数,您可能可以从1中随机抽样到该行数,并只读取该子集。我很欣赏这篇文章,尼克,但您建议如何从数据集中随机抽样?LyzandeR的方法(至少是我的实现)对我来说太慢了。感谢您的回答。行
    nl=read.table(pipe(“wc-l test.csv”)[[1]]
    我怀疑我遇到了与我的问题相同的问题。我的R控制台已经运行了20分钟,线路还没有结束。我将尝试一下gawk的想法,大致估计一下行数,然后再与您联系。