首页 > 解决方案 > 如何将 2.8 GB gzipped (40 GB TSV) 文件批量读取到 R 中?

问题描述

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

我在这里阅读了几个答案,但似乎没有一个有效 - 我怀疑它们不适合处理那么多数据。

简而言之,我该如何:

  1. 读取 3 GB 的 gzip 文件
  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()

标签: rdata.tablereadrr-bigmemory

解决方案


这更像是一个策略答案。

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

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

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

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

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

从那里你可以dplyr用来操作你的数据。祝你好运!


推荐阅读