如何将2.8 GB压缩(40 GB TSV)文件批量读取到R中?

时间:2018-10-24 01:04:17

标签: r data.table readr r-bigmemory

我有一个目录,其中包含31个压缩的TSV(2.8 GB压缩/ 40 GB未压缩)。我想根据1列的值有条件地导入所有匹配的行,然后合并为一个数据帧。

我在这里已经阅读了几个答案,但似乎都没有用,我怀疑它们并不是要处理那么多数据。

简而言之,我该怎么做:

  1. 读取3 GB的压缩文件
  2. 仅导入其列匹配特定值的行
  3. 将匹配的行合并为一个数据帧。

数据整洁,仅关注4列:日期,ip,类型(str),类别(str)。

我尝试使用read_tsv_chunked()的第一件事:

library(purrr)
library(IPtoCountry)
library(lubridate)
library(scales)
library(plotly)
library(tidyquant)
library(tidyverse)
library(R.utils)
library(data.table)

#Generate the path to all the files.
import_path <- "import/"
files <-  import_path %>% 
  str_c(dir(import_path))

#Define a function to filter data as it comes in.
call_back <- function(x, pos){
  unique(dplyr::filter(x, .data[["type"]] == "purchase"))
}

raw_data <- files %>%
  map(~ read_tsv_chunked(., DataFrameCallback$new(call_back),
      chunk_size = 5000)) %>%
  reduce(rbind) %>%
  as_tibble() # %>%

第一种方法只能处理9 GB的未压缩数据,而不能处理40 GB的数据。

使用fread()(相同的加载包)的第二种方法:

 #Generate the path to all the files.
    import_path <- "import/"
    files <-  import_path %>% 
      str_c(dir(import_path))

 bind_rows(map(str_c("gunzip - c", files), fread))

看起来好像开始工作,但随后被锁定。我无法弄清楚如何在select = c(colnames) / fread()调用内将map()参数传递给str_c(),更不用说对一列的过滤条件了。

2 个答案:

答案 0 :(得分:3)

这更多是一种策略性答案。

R将所有数据加载到内存中进行处理,因此,您正在查看的数据量会遇到问题。

我建议您做的,就是我要做的,是使用Apache Spark进行数据处理,并使用R包sparklyr与其接口。然后,您可以将数据加载到Spark中,在那里进行处理,然后将汇总的数据集检索回R中,以进行进一步的可视化和分析。

您可以在R Studio实例中本地安装Spark,并在那里做很多事情。如果您需要进一步的计算能力,请查看托管选项,例如AWS。

已阅读此https://spark.rstudio.com/

一个技术要点是,有一个sparklyr函数spark_read_text可以将定界的文本文件直接读取到Spark实例中。非常有用

您可以从此处使用dplyr来处理数据。祝你好运!

答案 1 :(得分:1)

首先,如果使用了基本的 read.table ,则无需使用 gunzip 的任何内容,因为它使用Zlib直接读取这些内容。如果指定了 colClasses 参数, read.table 的运行速度也将更快。

您可能需要编写一些自定义的 R 代码,以直接从31个TSV中的每一个中生成一个融化的数据帧,然后通过 rbind 对其进行累加。

拥有一台具有大量快速虚拟内存的计算机仍然会有所帮助。我经常按此顺序使用数据集,有时我会找到一个需要内存的Ubuntu系统,即使它具有32个内核。我有一个替代系统,在该系统中,我已经使操作系统确信SSD的内存更多,从而为我提供了有效的64 GB RAM。我发现这对于其中一些问题非常有用。它是Windows,因此我需要适当地设置 memory.limit(size = ...)

请注意,一旦使用 read.table 读取TSV,它就会被压缩,接近 gzip 提供的内容。如果这样做,您可能不需要大型系统。

如果发现要花费很长时间(我对此表示怀疑),请确保在两者之间的点上进行检查点和 save.image