【发布时间】:2021-10-15 04:44:58
【问题描述】:
我知道关于堆栈溢出还有其他关于在 R 中读取 csv 文件的最快方法的问题 - 并且已经得到解答; data.table 似乎是要走的路。但我有额外的要求。
我需要想出一个脚本来设置两组向量之间的差异操作(以查找两个向量中匹配的值的计数)。两组向量都将从两个不同目录 dirA 和 dirB 中的 csv 文件中获取。将 dirA 中的每个向量与 dirB 中的所有向量进行比较,并记录匹配数。 dirA 有大约 50 个文件,而 dirB 有 3000 个不同大小的文件(1 到 60 MB)。
以下是我使用 R 进行的尝试。它没有我预期的那么快(与在 Pandas 中实现的类似解决方案相比,此代码慢了 30%)。一次读取 3000 个文件需要 120 多秒。是否有我遗漏的东西,或者这是我在 R 中能得到的最好的东西——我是通过巧妙地一次性使用矢量化和多重比较来实现的?任何帮助表示赞赏。谢谢。
- 我正在使用 data.table 版本 1.13.6。
- 我想将所有内容都读取为字符串(有前导零和其他一些异常)
代码:
path_dirA <- "data/processed_data_dirA"
path_dirB <- "data/processed_data_dirB"
fn_dirA <- list.files(here(path_dirA), pattern="csv")
fn_dirB <- list.files(here(path_dirB), pattern="csv")
v_count_matched <- integer()
for (fn1 in fn_dirA) {
f1 <- data.table::fread(here(fn_dirA, fn1), colClasses = 'character')
for (fn2 in fn_dirB) {
f2 <- data.table::fread(here(fn_dirB, fn2), colClasses = 'character')
v_count_matched <- c(v_count_matched, length( fintersect(f1[,1],f2[,1]) ) )
}
}
}
【问题讨论】:
-
在某些情况下,
vroom在摄取文件方面比 data.table 更快,因为它为延迟加载编制索引。可能值得一试。 github.com/r-lib/vroom -
不是将
length( fintersect(f1[,1],f2[,1]) )连接到v_count_matched循环的每次迭代,而是创建一个向量v_count_matched,它是fn_dirA的长度,并像v_count_matched[fn1] = length( fintersect(f1[,1],f2[,1]) )一样填充它。 -
查看R Inferno 的第 2 圈。问题可能在于不断追加而不是读取文件。
-
如果您只比较第一列,则只能读取该列(在
fread中带有select参数)。 -
尝试更新
data.table,最近有一些性能改进可能会影响您的情况。
标签: r csv data.table