Data.table: fread 支持 .gz 文件格式

创建于 2014-07-04  ·  52评论  ·  资料来源: Rdatatable/data.table

我有数千个.gz文件,其中包含csv格式的数据 - 就.gz文件而言,总共大约 60GB。 解压缩它们并通过fread加载一些片段在第一步中变得非常痛苦。 我想知道是否可以改进fread的功能,使其可以像read.table一样读取压缩文件格式?

也许文件连接问题是高度相关的,如 #341、#543 和 #561 中所述。
其他一些参考:

http://stackoverflow.com/questions/5764499/decompress-gz-file-using-r

http://blog.revolutionanalytics.com/2009/12/r-tip-save-time-and-space-by-compressing-data-files.html

High feature request fread

最有用的评论

把我给 OS X 用户的小贴士放在这里。
OS X 上的zcat语法与其他 Linux 系统略有不同。 要读取*.gz文件,请使用以下调用:

dt <- fread(input = 'zcat < data.gz')

所有52条评论

如果您有很多文件,您可以只执行fread('zcat file.gz')或一些循环变体。

:Bump: 非常有用(并且经常出现)。

这是一篇 SO 帖子

是的,这将是一个非常有用的功能。 使用命令行充其量只是一个临时解决方案,因为它依赖于底层系统来提供解压工具。 例如,除非安装了 cygwin 等,否则“zcat”在 Windows 上不可用。

由于 FRead 是迄今为止 R 中读取文件的最佳工具,因此直接读取 gzipped/bziped/... 文件将获得巨大的性能提升。

我刚刚在我的电子邮件中看到@arun的颠簸,几小时前我正在摄取 200 多个这样的文件。 +1 有用

我同意@gbonamy直接从zip文件readding将是一个梦幻般的除了!

从与 unz() 的连接中读取也非常有用。 我有一个下载 zip 文件的功能,只读取一个文件然后将其丢弃。 所以如果我可以使用 fread(unz(zipfile, file = file)) 这将是一个很好的补充。

我 ++ 大约直接来自 gz 文件。 我个人每天都会使用它。

+1也来自我。

+1

+1

+1

+1

+1

我很好奇 - 人们要求这个主要是在 Windows 上工作吗? 我很难在 Linux 上看到对这种专业化的渴望。

我个人主要使用 .xz 压缩,但不在乎fread直接支持它 - 我经常管道未压缩的结果并在将其加载到 R 之前进行一些后处理(例如fread('xzcat file.xz | grep smth | awk blah') ) 并且我不喜欢依赖于fread的文件格式读取能力——我的 shell 进程几乎总是比fread实现的进程更先进。

:+1:

把我给 OS X 用户的小贴士放在这里。
OS X 上的zcat语法与其他 Linux 系统略有不同。 要读取*.gz文件,请使用以下调用:

dt <- fread(input = 'zcat < data.gz')

这可能不是最有效的方法,但它对我有用,您可能需要将unz更改为gzfile

zread <- function(zf,f,...){
  require(data.table)
  res <- fread(paste(readLines(tmp <- unz(zf,f)), collapse = "\n"),...)
  close(tmp)
  res
}

readLines非常慢...

@dselivanov它可以在小文件上完成工作,但从未在大文件上尝试过……我的方法可能做了很多无用的内存分配,将整个文件作为字符向量传递。

只需 zcat 文件,请参阅以前的帖子

周二2015年12月,8,gdkrmr [email protected]写道:

@dselivanov https://github.com/dselivanov它可以在小范围内完成工作
文件...我的方法可能做了很多无用的内存分配传递
整个文件作为字符向量。


直接回复此邮件或在 GitHub 上查看
https://github.com/Rdatatable/data.table/issues/717#issuecomment -162838134
.

+1 对于我们不幸的 Windows 用户和便携性。 fread不能接受连接可能是有原因的(如help("connections", package="base") ),但如果不是,那将是一个很好的便携解决方案。 也有助于解决一些常见的编码问题(例如 UTF-8 文件中的 BOM)。

+1 我们的生产服务器是 Linux,但我们在 Windows 机器上进行编码和测试。 将此功能内置到 fread 中将使我们能够创建在两种环境中都可以使用的代码版本。

+1

+1

zcat |不是大型数据文件的选项,因为:
gzip: stdout: No space left on device

@webbp除非你有一个不寻常的 /dev/shm 挂载 - 如果你不能将它zcat到 /dev/shm( fread在内部做了什么),那么我看不到本地支持会帮助你。 也许你只是没有足够的内存。

+1

@eantonya是的,我没有足够的内存; 我只有 32g + 64g 交换。 zcat file.tsv.gz > file.tsv 后跟 fread('file.tsv') 是一个足够简单的解决方法,但我和其他人 ( 1 2 3 ) 会很感激能提供适当的解决方案。

@webbp您应该将 /dev/shm(也就是您的虚拟内存)的大小调整为大于您的物理 RAM,并且您不会遇到该问题。 您的(未压缩)文件要么大于 RAM 大小的 1/2(但小于您的 RAM,否则未压缩文件的fread将失败)并且您将 shm 的默认值设置为 RAM 的一半,或者您在安装后增加了 RAM 并且没有更新 /etc/fstab。

+1

+1

+1 - 也适用于其他连接( gzfilebzfilexzfileunz

+1 我来自 fread / fwrite 的第一个愿望

@webbp ,我有相同的 pbm。 我不能使用 zcat,虽然它很漂亮,因为我的 AWS EC2 实例上 /dev/shm 的大小太小了。 我应该尝试将 /dev/shm 重定向到 EBS 磁盘,但还没有弄清楚如何。 同时,“zcat file.tsv.gz > file.tsv 后跟 fread('file.tsv')”是一种灵活的解决方法,但至少它有效。

另一种想法是使用特定的 tmp 目录。 任何的想法?

+1

+1

+1

是否可以使 R 包具有包含在同一界面中的 windows、mac、liunx 命令行工具。 然后我们可以在安装该软件包时将zcat用法与 fread 一起使用。

这种包的一个例子

我意识到如果您需要在包中打包 gzip windows 版本, CRAN 中将不允许使用这种包。 要么将其托管在其他地方,要么要求用户自己下载 gzip 窗口。

将文件解压缩到磁盘上的临时文件总是可行的,但由于磁盘访问,这可能会很慢。 如果我们将文件读入 RAM 中的原始向量,然后在将未压缩的原始向量提供给 fread 之前使用memDecompress进行解压缩,这会起作用吗?

我写了一个函数,将 zip、gz、bzip2、xz 解压缩到临时文件中,运行函数然后删除临时文件。 所以我们可以使用temp_unzip(file, fread, ...)

代码是纯 R,所以它应该适用于所有平台。 我觉得zcat方法对于 linux/mac 已经足够好了(有时我确实需要引用文件名),但对于 windows 来说太复杂了。

该代码的灵感来自R.utils但我真的不喜欢它默认删除输入文件的默认行为。 另外我认为R.utils作者只是修改了compressFile代码以用于decompressFile 。 需要分别调用gzfilebzfile进行压缩,但您不必调用gzfilebzfilexzfile分开是因为gzfile可以处理所有压缩格式(除了 zip,我使用了unzip )。

以下是一些基准:

library(microbenchmark)
microbenchmark(
  fread(eg_csv),
  fread(input = paste0("zcat < '", eg_gz, "'")), 
  temp_unzip(eg_bz, fread),
  temp_unzip(eg_zip, fread),
  temp_unzip(eg_gz, fread),
  times = 1)
Unit: seconds
                                          expr      min       lq     mean   median       uq
                                 fread(eg_csv) 2.117812 2.117812 2.117812 2.117812 2.117812
 fread(input = paste0("zcat < '", eg_gz, "'")) 1.984009 1.984009 1.984009 1.984009 1.984009
                      temp_unzip(eg_bz, fread) 6.304849 6.304849 6.304849 6.304849 6.304849
                     temp_unzip(eg_zip, fread) 2.481650 2.481650 2.481650 2.481650 2.481650
                      temp_unzip(eg_gz, fread) 2.487811 2.487811 2.487811 2.487811 2.487811
      max neval
 2.117812     1
 1.984009     1
 6.304849     1
 2.481650     1
 2.487811     1

需要注意的一件事是zcat解决方案似乎仅当文件存在于 R 启动的同一目录中时才有效:

Error in fread("zcat < data/directory/test.csv.gz") :
  File is empty: /var/folders/41/asdf_kj80000gn/T//RtmpwtAttt/fileebeb5e124cef

我忘记了这个问题并试图读取一个 gz 文件,结果却出现了一个神秘的错误,导致我再次浪费时间寻找解决方案。

3 年后,仍在等待这个基本修复。

经过进一步探索,我上面的错误只有在目录名中有空格时才会出现:

fread("zcat < data/directory\ one/test.csv.gz"

但不带下划线:

fread("zcat < data/directory_two/test.csv.gz"

并且可以通过再次转义反斜杠来缓解:

fread("zcat < data/directory\\ one/test.csv.gz"

希望这可以帮助。 否则, zcat解决方案工作正常。

StackOverflow 上的另一个例子,为什么需要这个功能:
data.table fread 错误 - gzip 文件 - 设置临时目录

怎么样:

library(readr)
DT = as.data.table(read_csv("myfile.gz"))

这是相当慢的。

- - - - 原始信息 - - - -
来自:韦伯菲利普斯
日期:2018/03/01下午 6:26 (GMT+00:00)
到:“Rdatatable/data.table”
抄送:米哈伊尔·斯皮瓦科夫,评论
主题: Re: [Rdatatable/data.table] 支持 fread 的 .gz 文件格式 (#717)

怎么样:

dt = as.data.table(read_csv("myfile.gz"))```


您收到此消息是因为您发表了评论。
直接回复本邮件,在 GitHub 上查看https://github.com/Rdatatable/data.table/issues/717#issuecomment-369684424 ,或者将线程静音https://github.com/notifications/unsubscribe-auth/ ABlQ65ZJPuwpxCfmJTuRZ1aBPh4Jejniks5taD06gaJpZM4CKNWu
Babraham Institute, Babraham Research Campus, Cambridge CB22 3AT Registered Charity No. 1053902。
本电子邮件中传输的信息仅针对收件人。 如果您误收到此邮件,请联系发件人并从您的系统中删除此电子邮件。 本电子邮件的内容仅代表发件人的观点,并不一定代表 Babraham Institute 的观点。 完整条件请访问: www.babraham.ac.uk http://www.babraham.ac.uk/terms

setDT 会比 as.data.table 快。 read_csv 用于什么工具
破解.gz?

2018 年 3 月 2 日凌晨 2:32,“mspivakov”通知@github.com 写道:

这是相当慢的。

- - - - 原始信息 - - - -
来自:韦伯菲利普斯
日期:2018/03/01下午 6:26 (GMT+00:00)
到:“Rdatatable/data.table”
抄送:米哈伊尔·斯皮瓦科夫,评论
主题:回复:[Rdatatable/data.table] 支持 fread 的 .gz 文件格式
(#717)

怎么样:

dt = as.data.table(read_csv("myfile.gz"))```


您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看 Rdatatable/data.table/issues/717#issuecomment-369684424>,或静音
线 ABlQ65ZJPuwpxCfmJTuRZ1aBPh4Jejniks5taD06gaJpZM4CKNWu>。
巴布拉汉姆研究所,巴布拉汉姆研究园区,剑桥 CB22 3AT
注册慈善机构编号 1053902。
本电子邮件中传输的信息仅针对
收件人。 如果您错误地收到了此信息,请联系发件人并
从您的系统中删除此电子邮件。 这封电子邮件的内容是
发件人的观点,不一定代表发件人的观点
巴布拉汉姆研究所。 完整条件请访问: www.babraham.ac.uk babraham.ac.uk/terms>


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/Rdatatable/data.table/issues/717#issuecomment-369686247
或静音线程
https://github.com/notifications/unsubscribe-auth/AHQQdZa08PZo9LKMGbnzMnmUeaspKxgVks5taD6wgaJpZM4CKNWu
.

@frenchja - 同意 - 虽然你可能更喜欢用 R 的shQuote来逃避这些空间

readr正在从内存中的连接(?gzfile)读取数据: https :

它用read_tokens_解析: https :

@frenchja这将如何与past0 ? 我现在有下面的代码,但这会引发错误:

SOME_DIR = "/Users/swvanderlaan/some_dir"
data <- fread('zcat < paste0(SOME_DIR,"/somedata.txt.gz")', 
                                                          header = TRUE, na.strings = "NA", 
                                                          verbose = TRUE, showProgress = TRUE)

啊,明白了,应该是这样的:

data <- 
  fread(paste0("zcat < '", SOME_DIR,"/somedata.txt.gz","'"), 
                                                          header = TRUE, na.strings = "NA", 
                                                          verbose = TRUE, showProgress = TRUE)

@swvanderlaan 对于这样的情况,我倾向于使用sprintf ; 您还应该使用file.pathshQuote来实现平台健壮性:

fread(sprintf('zcat %s', shQuote(file.path(SOME_DIR, 'somedata.txt.gz'))))
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

sengoku93 picture sengoku93  ·  3评论

arunsrinivasan picture arunsrinivasan  ·  3评论

franknarf1 picture franknarf1  ·  3评论

alex46015 picture alex46015  ·  3评论

nachti picture nachti  ·  3评论