r- 从 zip 读取并与数据框列中的值匹配
r- Reading from zip and matching with values from dataframe column
我试图通过读取两个数据集来制作一个数据帧,但我使用的方法非常慢 - 读取和处理 600Mb 的数据可能需要长达 10 个小时。我相信一定有一种更快的方法可以做到这一点,但我想我看不出是什么似乎在减慢这个过程。以下是介绍这些步骤的可重现示例。
所需的软件包:
library(tidyverse)
第一组是 .csv
文件。可以使用以下内容重新创建示例:
info <- data.frame(identification = c("a", "b", "c", "d", "e"), attr = c(0:4))
info %>% write_csv("folder/info.csv")
第二个是压缩文件。可以使用以下内容重新创建示例:
a <- data.frame(var = c(41:50), val = c(31:40))
a %>% write_csv("folder/file/a_df.csv")
b <- data.frame(var = c(41:50), val = c(31:40))
b %>% write_csv("folder/file/b_df.csv")
c <- data.frame(var = c(41:50), val = c(31:40))
c %>% write_csv("folder/file/c_df.csv")
d <- data.frame(var = c(41:50), val = c(31:40))
d %>% write_csv("folder/file/d_df.csv")
e <- data.frame(var = c(41:50), val = c(31:40))
e %>% write_csv("folder/file/e_df.csv")
files2zip <- dir('folder/file/', full.names = TRUE)
zip(zipfile = 'testZip', files = files2zip)
我使用的方法如下:
data1 <- read_csv("folder/info.csv")
read_from_zip <- function(identification) {
fn <- paste0("folder/file/", identification, ".csv")
# read zip files
zip_file <- paste0("./folder/testZip.zip")
id_2_zip <- unzip( zip_file
,files = fn)
df <- read_csv(id_2_zip)
}
df <- data1 %>% group_by(identification) %>% nest() %>%
mutate(trj = map(identification, read_from_zip))
df <- df %>% select(identification, trj) %>% unnest()
我猜这样的东西会起作用:
tmpdir <- tempfile()
dir.create(tmpdir)
一个方便的向量,如果你需要的话:
filesvec <- paste0(letters[1:5], '.csv')
请注意,这需要是压缩文件中列出的 "verbatim",包括任何前导目录。 (您可以使用 junkpaths=TRUE
代替 unzip()
或 system('unzip -j ...')
来删除前导路径。)过去,我通过快速调用 unzip(zipfile, list=TRUE)
创建了这个文件名向量和 grep
ing 输出。这样,如果您小心,那么您将 (a) 在提取文件之前始终知道文件丢失,并且 (b) 不会在 unzip()
或 non-zero return 代码中引起异常来自 system('unzip ...')
。你可能会这样做:
filesvec <- unzip(zipfile, list=TRUE)
filesvec <- filesvec[ grepl("\.csv$", filesvec) ]
# some logic to ensure you have some or all of what you need
然后其中一个:
unzip(zipfile, files=filesvec, exdir=tmpdir)
system(paste(c("unzip -d", shQuote(c(tempdir(), 'foo.zip', 'a.csv','b.csv')))))
从这里,您可以通过以下方式访问文件:
alldata <- sapply(file.path(tmpdir, filesvec), read.csv, simplify=FALSE)
其中列表的名字是文件名(包括前导路径?),内容应该都是data.frame
s.
完成后,是否清理临时文件取决于您对临时文件的强迫症程度。您的 OS 可能会 一段时间后为您清理它们。如果您对 space 很紧张或只是偏执狂,您可以使用以下方法进行清理:
ign <- sapply(file.path(tmpdir, filesvec), unlink)
unlink(tmpdir, recursive=TRUE) # remove the temp dir we created
(你可以只使用第二个命令,但如果你使用不同的 temp-directory 方法,我想我会小心。)
我试图通过读取两个数据集来制作一个数据帧,但我使用的方法非常慢 - 读取和处理 600Mb 的数据可能需要长达 10 个小时。我相信一定有一种更快的方法可以做到这一点,但我想我看不出是什么似乎在减慢这个过程。以下是介绍这些步骤的可重现示例。
所需的软件包:
library(tidyverse)
第一组是 .csv
文件。可以使用以下内容重新创建示例:
info <- data.frame(identification = c("a", "b", "c", "d", "e"), attr = c(0:4))
info %>% write_csv("folder/info.csv")
第二个是压缩文件。可以使用以下内容重新创建示例:
a <- data.frame(var = c(41:50), val = c(31:40))
a %>% write_csv("folder/file/a_df.csv")
b <- data.frame(var = c(41:50), val = c(31:40))
b %>% write_csv("folder/file/b_df.csv")
c <- data.frame(var = c(41:50), val = c(31:40))
c %>% write_csv("folder/file/c_df.csv")
d <- data.frame(var = c(41:50), val = c(31:40))
d %>% write_csv("folder/file/d_df.csv")
e <- data.frame(var = c(41:50), val = c(31:40))
e %>% write_csv("folder/file/e_df.csv")
files2zip <- dir('folder/file/', full.names = TRUE)
zip(zipfile = 'testZip', files = files2zip)
我使用的方法如下:
data1 <- read_csv("folder/info.csv")
read_from_zip <- function(identification) {
fn <- paste0("folder/file/", identification, ".csv")
# read zip files
zip_file <- paste0("./folder/testZip.zip")
id_2_zip <- unzip( zip_file
,files = fn)
df <- read_csv(id_2_zip)
}
df <- data1 %>% group_by(identification) %>% nest() %>%
mutate(trj = map(identification, read_from_zip))
df <- df %>% select(identification, trj) %>% unnest()
我猜这样的东西会起作用:
tmpdir <- tempfile()
dir.create(tmpdir)
一个方便的向量,如果你需要的话:
filesvec <- paste0(letters[1:5], '.csv')
请注意,这需要是压缩文件中列出的 "verbatim",包括任何前导目录。 (您可以使用 junkpaths=TRUE
代替 unzip()
或 system('unzip -j ...')
来删除前导路径。)过去,我通过快速调用 unzip(zipfile, list=TRUE)
创建了这个文件名向量和 grep
ing 输出。这样,如果您小心,那么您将 (a) 在提取文件之前始终知道文件丢失,并且 (b) 不会在 unzip()
或 non-zero return 代码中引起异常来自 system('unzip ...')
。你可能会这样做:
filesvec <- unzip(zipfile, list=TRUE)
filesvec <- filesvec[ grepl("\.csv$", filesvec) ]
# some logic to ensure you have some or all of what you need
然后其中一个:
unzip(zipfile, files=filesvec, exdir=tmpdir)
system(paste(c("unzip -d", shQuote(c(tempdir(), 'foo.zip', 'a.csv','b.csv')))))
从这里,您可以通过以下方式访问文件:
alldata <- sapply(file.path(tmpdir, filesvec), read.csv, simplify=FALSE)
其中列表的名字是文件名(包括前导路径?),内容应该都是data.frame
s.
完成后,是否清理临时文件取决于您对临时文件的强迫症程度。您的 OS 可能会 一段时间后为您清理它们。如果您对 space 很紧张或只是偏执狂,您可以使用以下方法进行清理:
ign <- sapply(file.path(tmpdir, filesvec), unlink)
unlink(tmpdir, recursive=TRUE) # remove the temp dir we created
(你可以只使用第二个命令,但如果你使用不同的 temp-directory 方法,我想我会小心。)