r - 如何将 2.8 GB gzipped (40 GB TSV) 文件批量读取到 R 中?
问题描述
我有一个包含 31 个 gzip 压缩 TSV(2.8 GB 压缩/40 GB 未压缩)的目录。我想根据 1 列的值有条件地导入所有匹配的行,并组合成一个数据框。
我在这里阅读了几个答案,但似乎没有一个有效 - 我怀疑它们不适合处理那么多数据。
简而言之,我该如何:
- 读取 3 GB 的 gzip 文件
- 仅导入其列与某个值匹配的行
- 将匹配的行合并到一个数据框中。
数据很整齐,只有 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()
解决方案
这更像是一个策略答案。
R 将所有数据加载到内存中进行处理,因此您会遇到正在查看的数据量的问题。
我建议你做的,也就是我做的,是使用 Apache Spark 进行数据处理,并使用 R 包 sparklyr 来连接它。然后,您可以将数据加载到 Spark 中,在那里对其进行处理,然后将汇总的数据集检索回 R 中以进行进一步的可视化和分析。
您可以在 R Studio 实例中本地安装 Spark,并在那里做很多事情。如果您需要更多计算能力,请查看 AWS 等托管选项。
一个技术点,有一个sparklyr
函数spark_read_text
可以将分隔的文本文件直接读取到 Spark 实例中。它非常有用。
从那里你可以dplyr
用来操作你的数据。祝你好运!
推荐阅读
- azure - 使用资源所有者密码凭据流的 AD B2C 非交互式/无头身份验证
- c# - 如何从列表中获取重复的项目子字符串?C#
- sql - 如何在 SQL 中连接 3 个表
- internet-explorer - 在 IE 中为样式元素编辑为 HTML
- windows - 一起使用 InkCanvas、Inktoolbar 和地图
- html - 是否所有浏览器都会忽略 html 中的空行
- php - PHP foreach if isset
- c# - ASP.NET MVC 中的自定义路由绕过主控制器/索引
- jquery - 我想在jquery中获取数据
- jenkins - 将 groovy 字符串变量传递给 jenkins 作业 dsl 授权