Существует множество документации о том, как читать несколько CSV и связывать их в один фрейм данных. У меня есть более 5000 файлов CSV, которые мне нужно прочитать и привязать к одной структуре данных.
В частности, я следил за обсуждением здесь: Проблема при загрузке нескольких файлов .csv в один фрейм данных в R с помощью rbind
Странно то, что base R работает намного быстрее, чем любое другое решение, которое я пробовал.
Вот как выглядит мой CSV:
> head(PT)
Line Timestamp Lane.01 Lane.02 Lane.03 Lane.04 Lane.05 Lane.06 Lane.07 Lane.08
1 PL1 05-Jan-16 07:17:36 NA NA NA NA NA NA NA NA
2 PL1 05-Jan-16 07:22:38 NA NA NA NA NA NA NA NA
3 PL1 05-Jan-16 07:27:41 NA NA NA NA NA NA NA NA
4 PL1 05-Jan-16 07:32:43 9.98 10.36 10.41 10.16 10.10 9.97 10.07 9.59
5 PL1 05-Jan-16 07:37:45 9.65 8.87 9.88 9.86 8.85 8.75 9.19 8.51
6 PL1 05-Jan-16 07:42:47 9.14 8.98 9.29 9.04 9.01 9.06 9.12 9.08
Я создал три метода для чтения и привязки данных. Файлы находятся в отдельном каталоге, который я определяю как:
dataPath <- "data"
PTfiles <- list.files(path=dataPath, full.names = TRUE)
Метод 1: База R
classes <- c("factor", "character", rep("numeric",8))
# build function to load data
load_data <- function(dataPath, classes) {
tables <- lapply(PTfiles, read.csv, colClasses=classes, na.strings=c("NA", ""))
do.call(rbind, tables)
}
#clock
method1 <- system.time(
PT <- load_data(path, classes)
)
Метод 2: read_csv
В этом случае я создал функцию-оболочку для read_csv, чтобы использовать
#create wrapper function for read_csv
read_csv.wrap <- function(x) { read_csv(x, skip = 1, na=c("NA", ""),
col_names = c("tool", "timestamp", paste("lane", 1:8, sep="")),
col_types =
cols(
tool = col_character(),
timestamp = col_character(),
lane1 = col_double(),
lane2 = col_double(),
lane3 = col_double(),
lane4 = col_double(),
lane5 = col_double(),
lane6 = col_double(),
lane7 = col_double(),
lane8 = col_double()
)
)
}
##
# Same as method 1, just uses read_csv instead of read.csv
load_data2 <- function(dataPath) {
tables <- lapply(PTfiles, read_csv.wrap)
do.call(rbind, tables)
}
#clock
method2 <- system.time(
PT2 <- load_data2(path)
)
Метод 3: read_csv
+ dplyr::bind_rows
load_data3 <- function(dataPath) {
tables <- lapply(PTfiles, read_csv.wrap)
dplyr::bind_rows(tables)
}
#clock
method3 <- system.time(
PT3 <- load_data3(path)
)
Я не могу понять, почему методы read_csv и dplyr медленнее в течение прошедшего времени, тогда как они должны быть быстрее. Время ЦП уменьшилось, но почему увеличилось затраченное время (файловая система)? Что тут происходит?
Изменить - я добавил метод data.table
, как было предложено в комментариях.
Метод 4 data.table
library(data.table)
load_data4 <- function(dataPath){
tables <- lapply(PTfiles, fread)
rbindlist(tables)
}
method4 <- system.time(
PT4 <- load_data4(path)
)
Метод data.table
- самый быстрый с точки зрения ЦП. Но все еще остается вопрос, что происходит с read_csv
методами, которые делают их такими медленными.
> rbind(method1, method2, method3, method4)
user.self sys.self elapsed
method1 0.56 0.39 1.35
method2 0.42 1.98 13.96
method3 0.36 2.25 14.69
method4 0.34 0.67 1.74
data.table::fread()
самый быстрый - person cirofdo   schedule 17.05.2017data.table::rbindlist()
, чтобы склеить их вместе. - person Dirk Eddelbuettel   schedule 17.05.2017data.table
, и это быстро. У меня все еще остается вопрос, почему методread_csv
такой медленный. - person Lloyd Christmas   schedule 17.05.2017read_csv
, вы должны иметь возможность воспроизвести разницу в скорости при чтении одного гигантского CSV без всяких прихотей и привязок. - person joran   schedule 17.05.2017map_dfr(list.files(), read_csv)
- person thus__   schedule 10.02.2020