複数のファイルを一度に読みこむ方法
Rで複数のファイルを一度に読み込みたい場合がたまにある。
例えば、売り上げのデータが日付ごとに分かれたファイルに収められているような場合。
しょっちゅう発生するわけでもなく、いつも忘れてしまって調べるのに時間がかかるのでここにメモしておく。
ここではそうしたファイルが一つのフォルダに収められているものとする。
方法は大きく三つある
- Tidyverse流(read_csv & map_dfr)
- data.table流(fread & rbindlist)
- vroom流(vroom)
デモデータの用意
必要なパッケージを読み込みつつ、実験用のデモデータの用意。
library(tidyverse) library(data.table) library(vroom) library(microbenchmark) DIR <- "data/" row_n <- 10000 col_n <- 10 files <- 10 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) }
Tidyverse流
DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% set_names() %>% map_dfr(read_csv, .id = "file_name" ) -> dat
data.table流
DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% set_names() %>% map(fread) %>% rbindlist(idcol = "file_name") -> dat
vroom流
DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% vroom(id = "file_name") -> dat
比較
Tidyverseに慣れてる人なら read_csv と map_dfr を組み合わせるのが分かりやすいだろう。
data.table流はとにかく速い。爆速。
vroomはファイル数が多くなるとエラーになる。今後に期待。
# read_csv + map_dfr ----------------------------------------------------------------- read_csv_and_map_dfr <- function() { DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% set_names() %>% map_dfr(read_csv, .id = "file_name" ) } # fread + rbindlist --------------------------------------------------------- fread_and_rbindlist <- function() { DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% set_names() %>% map(fread) %>% rbindlist(idcol = "file_name") } # vroom ------------------------------------------------------------------- # ファイル数が多いとエラーになる場合がある。 my_vroom <- function() { DIR %>% list.files(pattern = "*.csv", full.names = TRUE) %>% vroom(id = "file_name") } # microbenchimark --------------------------------------------------------- gc() gc() compare <- microbenchmark( "read_csv & map_dfr" = read_csv_and_map_dfr(), "fread & rbindlist" = fread_and_rbindlist(), "vroom" = my_vroom(), times = 30L ) compare autoplot(compare) + labs(title = "R 3.6.1")
以上。