【问题标题】:R - Sorting a large amount of data efficiently - memory issueR - 有效地对大量数据进行排序 - 内存问题
【发布时间】:2016-07-31 00:34:52
【问题描述】:

强制性系统设置以防万一: 运行 Windows 10、R 3.2.3 英特尔酷睿 i7 2600k。 16 GB 内存。 R 被设置为可以访问尽可能多的 RAM。

你好!

我有几百个文件,每个文件都有一个大小为 Nx29 或 Nx31 的数据框。

我正在合并每个数据帧中重叠的 ~4 列。 所以 ID1、ID2、日期、文本。我正在按日期排序。

所以问题是,这些 N 在某些文件中可能是几十行,而在其他文件中可能是几百万行。

我最初的想法是

Create a blank data frame
Loop -->
    Open a file
    Add that file to the Dataframe.
    Remove any duplicate rows (they happen semi-frequently)
    Open the next file.

但是,即使这样做也会导致我的数据框变得太大并且内存不足。

我会考虑写入文件,但这可能会有问题,因为假设我

Read file
Write to file
Open next file
Repeat.

然后,一旦我将所有内容都保存在 1 个大文件中,我可能无法将其加载到 R 中,因为如果单个组件不能一次全部放入内存中,那么组合起来也可能不会。

但是,我希望它全部按日期排序,并且每个文件可以包含大约 45 天左右的数据,因此很难找到一种方法来做到这一点。

那么我怎样才能有效地将我的所有数据放在一起以便能够在不破坏 R 的情况下对其进行排序呢?

谢谢!

【问题讨论】:

  • 查看这些文件的一些示例摘录以及您迄今为止尝试过的代码会很有帮助。
  • 也许你可以file.append() 到一个独特的文件,然后导入它。
  • 我遇到了类似的问题,只是单个数据集太大而无法放入内存。我最终使用 data.table 的fread 来读取文件块,然后处理这些较小的块并将临时文件保存到磁盘。在一个单独的 R 脚本以及一个新的 R 会话中,我组合并处理了这些中间文件。不确定在您的情况下是否可以进行中间处理,但可能值得考虑。在我自己的情况下,我不得不使用fread,因为 read.table 不会释放读取第 1:N-1 行的内存,即使我告诉它从第 N 行开始。
  • This post 可能会有所帮助。

标签: r sorting data-processing


【解决方案1】:

一种可能是沿着以下方法使用方法 行,我假设您已经有列表/矢量 my_files指定要打开的所有文件。

  1. 在读取文件的@ 987654322创建帮助函数 并返回具有两列的矩阵:一个指定的矩阵 有关@ 987654323的信息,以及包含线路编号的信息, 但随着-1的扭曲用于您要跳过的行 (后者是例如,重复的行)。这可能是 也是一个想念,只要一个额外的一步 将保留稍后的内容,并在其中排序 根据日期。

  2. 使用lapply 987654326 @ my_inspect, 您将有一个列表,其中包含有关所需日期的信息 为了在最后进行排序信息。

  3. 如果由my_inspect创建的矩阵已被排序 日期,它应该是一个相当简单的任务来标识文件 拥有第一个约会,有些环建筑可以是例如是 用于通过文件工作,提取匹配的行 正在调查的日期,然后将这些行保存到新文件。

这种方法可能不是最有效的,但我认为它 应该可以以这种方式完成它。你可能还是 需要将结果划分为几个文件,如果是这样的话 它可能是添加一个簿记 em>文件,可以通知您的文件 关于Date-Ranges的代码不同文件包含。

【讨论】:

    【解决方案2】:

    如果没有关于您的数据文件和代码的更多信息,很难提供更具体的分析,但我将演示如何解决这个问题。

    首先,关于将数据文件读入 R 会话,我曾多次发现 data.table 包中的 fread() 函数比 read.table()/@ 更高效、更灵活987654325@/read.csv2() 系列由基础 R 提供。此外,由于使用 data.table 对象通常比普通 data.frame 对象在许多类型的操作中提供性能优势,尤其是在您使用大数据,我强烈建议在使用 R 编码时进入 data.table 世界。

    这里我生成了一些测试数据,特别是5个data.tables:

    library(data.table);
    
    ## generate data
    set.seed(0L);
    NR <- 10L; NF <- 5L;
    for (f in seq_len(NF)) {
        n <- paste0('dt',f);
        assign(n,cbind(
            data.table(
                ID1=sample(1:100,NR),
                ID2=sample(1:100,NR),
                Date=sample(seq(as.Date('2016-01-01'),as.Date('2016-12-31'),1L),NR),
                Text=n
            ),
            replicate(sample(10:15,1L),sample(seq_len(NR))) ## varying column set
        ));
    };
    dt1; ## just generated 5 of these
    ##     ID1 ID2       Date Text V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
    ##  1:  90   7 2016-10-11  dt1  5  9  5 10  4  5  3  7 10  10   6   7
    ##  2:  27  21 2016-12-07  dt1  6  6  8  3  8  7  1  4  7   5   1   6
    ##  3:  37  18 2016-03-18  dt1  4  7  4  4  3  4  6  3  3   4   9   2
    ##  4:  56  67 2016-08-24  dt1  2  4  2  9  9  3  7 10  4   2   5   8
    ##  5:  88  37 2016-02-15  dt1 10  8  1  8  7 10  5  9  1   9  10   5
    ##  6:  20  74 2016-04-06  dt1  8 10  6  2  5  2  4  2  6   3   3   3
    ##  7:  85  47 2016-05-19  dt1  9  1  7  5 10  9  2  1  8   6   7   1
    ##  8:  96  97 2016-01-05  dt1  1  2  9  7  2  1  8  5  5   1   2   9
    ##  9:  61  92 2016-05-16  dt1  7  3  3  1  6  8 10  8  9   8   4   4
    ## 10:  58  35 2016-11-06  dt1  3  5 10  6  1  6  9  6  2   7   8  10
    

    现在将 data.table 对象写入磁盘文件:

    ## write files
    for (f in seq_len(NF)) {
        n <- paste0('dt',f);
        write.table(get(n),paste0(n,'.txt'),row.names=F);
    };
    

    以下代码可用于将磁盘文件读入单个 data.table 对象。我正在使用fread()select 参数来排除除我们感兴趣的4 列之外的所有列,这对于提高效率和减轻RAM 的负载很重要。它还确保rbind() 调用不会由于参数中的列集不一致而失败。

    ## read files into single data.table
    fns <- list.files(pattern='^dt.*\\.txt$');
    fns;
    ## [1] "dt1.txt" "dt2.txt" "dt3.txt" "dt4.txt" "dt5.txt"
    sel <- c('ID1','ID2','Date','Text');
    dt <- do.call(rbind,lapply(fns,function(fn) fread(fn,select=sel)));
    

    最后,我们可以按照Date列对data.table进行排序,如下:

    dt[order(Date)];
    ##     ID1 ID2       Date Text
    ##  1:  96  97 2016-01-05  dt1
    ##  2:  74  10 2016-01-13  dt5
    ##  3:  11  26 2016-01-20  dt4
    ##  4:  86   7 2016-01-24  dt4
    ##  5:  24  65 2016-01-28  dt5
    ##  6:  10  17 2016-01-31  dt3
    ##  7:  88  37 2016-02-15  dt1
    ##  8:  54  61 2016-02-21  dt4
    ##  9:   4  89 2016-02-28  dt4
    ## 10:  14  10 2016-03-11  dt3
    ## 11:  37  18 2016-03-18  dt1
    ## 12:  39  88 2016-03-27  dt5
    ## 13:  20  74 2016-04-06  dt1
    ## 14:  50  37 2016-04-06  dt3
    ## 15:  12  77 2016-05-07  dt3
    ## 16:  38  51 2016-05-15  dt4
    ## 17:  61  92 2016-05-16  dt1
    ## 18:  49  85 2016-05-17  dt2
    ## 19:  85  47 2016-05-19  dt1
    ## 20:  44  76 2016-05-22  dt2
    ## 21:  69  52 2016-05-31  dt5
    ## 22:  27  41 2016-06-18  dt4
    ## 23:  66  96 2016-06-28  dt3
    ## 24:  62  40 2016-07-10  dt5
    ## 25:  15  33 2016-07-17  dt5
    ## 26:  72  36 2016-07-28  dt4
    ## 27:  26  67 2016-08-04  dt2
    ## 28:  46  12 2016-08-05  dt4
    ## 29:  90  82 2016-08-05  dt5
    ## 30:  86  97 2016-08-11  dt3
    ## 31:  62  29 2016-08-18  dt2
    ## 32:  50   6 2016-08-19  dt2
    ## 33:  56  67 2016-08-24  dt1
    ## 34:  62  13 2016-08-25  dt3
    ## 35:  78  42 2016-08-26  dt4
    ## 36:  91  70 2016-09-12  dt5
    ## 37:  33  46 2016-09-19  dt3
    ## 38:   8  32 2016-09-23  dt2
    ## 39:  23  59 2016-10-04  dt5
    ## 40:  90   7 2016-10-11  dt1
    ## 41:  56  89 2016-11-02  dt2
    ## 42:  98  49 2016-11-03  dt3
    ## 43:  58  35 2016-11-06  dt1
    ## 44:  33  44 2016-11-07  dt2
    ## 45:  20  31 2016-11-18  dt2
    ## 46:  18  40 2016-11-19  dt2
    ## 47:  27  21 2016-12-07  dt1
    ## 48:   5   7 2016-12-13  dt3
    ## 49:  27  81 2016-12-13  dt5
    ## 50:   5  90 2016-12-22  dt4
    ##     ID1 ID2       Date Text
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 2016-07-16
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      相关资源
      最近更新 更多