続々・複数のファイルを一度に読みこむ方法
過去2回の続きでこれが最後(多分)。
複数のファイルを一度に読みこむ方法 - bob3’s blog
続・複数のファイルを一度に読みこむ方法 - bob3’s blog
前回、data.table::fread() を foreach で並列化したパターンを追加したのだけど、data.table::fread() はそもそも並列化されているということを思い出しました。
大変な無駄をしていたわけです。
このままだと並列化によって速くなるか否かが不明なままですので、readr::read_csv() を並列化して速さを確認してみます。
結論から言うとやっぱり fread & rbindlist が最速。
でも read_csv() も並列化した分は速くなってます。
まあ、通常は fread & rbindlist でいいと思います。
# demo data --------------------------------------------------------------- library(tidyverse) library(data.table) library(doParallel) library(microbenchmark) DIR <- "data/" row_n <- 10000 col_n <- 10 files <- 365 file_names <- paste0(DIR, formatC(1:files, width = 3, flag = "0"), ".csv") for (i in file_names) { rnorm(col_n * row_n) %>% round(4) %>% matrix(row_n, col_n) %>% data.frame() %>% fwrite(i) } # read_csv + map_dfr ----------------------------------------------------------------- read_csv_and_map_dfr <- function() { DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% set_names() %>% map_dfr( read_csv, progress = FALSE, .id = "file_name" ) } # fread + rbindlist --------------------------------------------------------- fread_and_rbindlist <- function() { file_names <- list.files(DIR, pattern = "*.csv", full.names = TRUE) tmp <- map(file_names, fread, showProgress = FALSE) setattr(tmp, "names", file_names) rbindlist(tmp, idcol = "file_name") } # 並列化 --------------------------------------------------------------------- cores <- detectCores(logical = FALSE) # コア数確認 cl <- makeCluster(cores) registerDoParallel(cl) clusterEvalQ(cl, c(library(readr), library(foreach))) my_foreach <- function() { file_names <- list.files(DIR, pattern = "*.csv", full.names = TRUE) tmp1 <- foreach(i = file_names) %dopar% { read_csv(i) } bind_rows(tmp1, .id = "files") %>% left_join(tibble(file_names = file_names, files = as.character(1:length(file_names))), by = "files") %>% select(-files) } # microbenchimark --------------------------------------------------------- gc() gc() compare <- microbenchmark( "read_csv & map_dfr" = read_csv_and_map_dfr(), "fread & rbindlist" = fread_and_rbindlist(), "doParallel & read_csv & bind_rows" = my_foreach(), times = 30L ) compare autoplot(compare) + labs(title = "R 3.6.1")