首页 > 解决方案 > R 中读取和比较 CSV 文件的最快方法

问题描述

我知道在堆栈溢出方面还有其他关于在 R 中读取 csv 文件的最快方法的问题 - 并且已经得到解答;data.table 似乎是要走的路。但我有额外的要求。

我需要想出一个脚本来设置两组向量之间的差异操作(以查找两个向量中匹配的值的计数)。两组向量都将从两个不同目录 dirA 和 dirB 中的 csv 文件中获取。将 dirA 中的每个向量与 dirB 中的所有向量进行比较,并记录匹配数。dirA 有大约 50 个文件,而 dirB 有 3000 个不同大小的文件(1 到 60 MB)。

下面是我使用 R 进行的尝试。它没有我预期的那么快(与 Pandas 中实现的类似解决方案相比,此代码慢了 30%)。一次读取 3000 个文件需要 120 多秒。是否有我遗漏的东西,或者这是我在 R 中能得到的最好的东西——我是通过巧妙地一次性使用矢量化和多重比较来实现的?任何帮助表示赞赏。谢谢你。

代码:

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]) ) )

    }
  }
}

标签: rcsvdata.table

解决方案


一种可能的加速方法是使用索引来添加数据而不是连接:

fn_dirA <- list.files(here(path_dirA), pattern="csv")
fn_dirB <- list.files(here(path_dirB), pattern="csv")
v_count_matched <- vector(NA, length(fn_dirA)*length(n_dirA))


counter = 0
for (fn1 in fn_dirA) {
  f1 <- data.table::fread(here(fn_dirA, fn1), colClasses = 'character')
 
  for (fn2 in fn_dirB) {
    counter = counter + 1
    f2 <- data.table::fread(here(fn_dirB, fn2), colClasses = 'character')
    v_count_matched[counter] <- length( fintersect(f1[,1],f2[,1]))

    }
  }
}

推荐阅读