在R中将一个原始文件解压到内存中

8

我需要从互联网上下载一个压缩的csv文件,将其解压并以data.frame形式加载到内存中。有没有一种方法可以在仅使用内存的情况下完成整个过程,而不必读写磁盘?以下是我尝试过的:

library(RCurl)
file <- getURL(url, userpwd='user:pwd')
tf <- tempfile()
writeBin(content(file, "raw"), tf)
tf <- unzip(tf, exdir=tempdir())
data <- read.csv(tf)
unlink(tf)

我认为这里使用的writeBinunzipread.csv会导致昂贵的磁盘I/O,但是我不知道如何改进它。


我会非常惊讶于写入和解压文件所涉及的延迟比初始下载更慢?但你可以尝试使用unz()函数。 - Forrest R. Stevens
@ForrestR.Stevens,能否更详细地解释一下您是如何使用“unz”函数来完成此任务的?这对我来说并不是很容易。 - Bamqf
请使用vroom进行操作。https://vroom.r-lib.org/index.html - Andre Wildberg
2个回答

0

我认为使用unz()的这个例子可以让你更接近目标,它会打开与你的Zip归档中的单个文件的连接,尽管如果unz()函数实际上没有将文件解压到磁盘上,我会感到惊讶,但我还没有检查过:

##  Create a sample data.frame object:
d <- data.frame(a=rnorm(40), b=rnorm(40))

##  Write this data.frame to two separate CSV files, and zip
##    them together into a new archive:
write.csv(d, file="d.csv")
write.csv(d, file="d_2.csv")
zip("d.zip", c("d.csv", "d_2.csv"))

##  In this case, we will open a file connection to a single file 
##    inside the zip archive, and read the data in using read.csv():
f <- unz("d.zip", "d_2.csv")
a <- read.csv( f )
head(a)

在我的Win 7系统上,zip函数给出了警告信息:运行命令'“zip”-r9X“d.zip”“d.csv”“d_2.csv”'的状态为127,然后unz无法打开连接。这是一个可重现的错误吗? - Bamqf
嗯,你可能没有安装系统路径中可用的Zip应用程序... 你可以安装Rtools并确保Rtools/bin在你的PATH中(你可以运行以下命令检查:shell("PATH")),或者只需使用自己的Zip文件测试该函数,而不是使用我的脚本创建它? - Forrest R. Stevens
我尝试过了,似乎unz无法将文件解压到磁盘上,但我仍然无法让它从URL中提取数据,而不是本地zip文件,特别是在我的情况下,用户名和密码都有'@'符号,这会混淆URL解析器。 - Bamqf
当然,你必须先下载文件吧?你不能从非本地文件解压缩东西吧? - Forrest R. Stevens
是的,我可以使用getURL下载文件,并将其直接下载到内存中。 我想知道如何解压缩我的示例中的file变量并将其解析为data.frame,而无需将其写入磁盘作为本地文件。 unz似乎仅适用于本地文件,而不适用于内存中的原始二进制文件。 - Bamqf
似乎你需要将它写入磁盘。 - Forrest R. Stevens

0

不需要额外解压缩。使用tidyverse函数read_csv()。 以.zip或.gz结尾的文件将自动解压缩。

您还可以通过此函数避免使用临时文件。以https://或ftp://开头的文件名将自动下载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接