Я працював над цим сьогодні над data.frame (дійсно таблицею даних) з мільйонами спостережень та 35 стовпців. Моєю метою було повернути список файлів data.frames (data.tables) з кожним рядком. Тобто я хотів розділити кожен рядок на окремий data.frame і зберегти їх у списку.
Ось два способи, які я придумав, були приблизно в 3 рази швидшими, ніж split(dat, seq_len(nrow(dat)))
для цього набору даних. Нижче я орієнтую три методи на рядку 7500, набір даних із 5 стовпців ( райдужка повторюється 50 разів).
library(data.table)
library(microbenchmark)
microbenchmark(
split={dat1 <- split(dat, seq_len(nrow(dat)))},
setDF={dat2 <- lapply(seq_len(nrow(dat)),
function(i) setDF(lapply(dat, "[", i)))},
attrDT={dat3 <- lapply(seq_len(nrow(dat)),
function(i) {
tmp <- lapply(dat, "[", i)
attr(tmp, "class") <- c("data.table", "data.frame")
setDF(tmp)
})},
datList = {datL <- lapply(seq_len(nrow(dat)),
function(i) lapply(dat, "[", i))},
times=20
)
Це повертається
Unit: milliseconds
expr min lq mean median uq max neval
split 861.8126 889.1849 973.5294 943.2288 1041.7206 1250.6150 20
setDF 459.0577 466.3432 511.2656 482.1943 500.6958 750.6635 20
attrDT 399.1999 409.6316 461.6454 422.5436 490.5620 717.6355 20
datList 192.1175 201.9896 241.4726 208.4535 246.4299 411.2097 20
Хоча відмінності не такі великі, як у моєму попередньому тесті, прямий setDF
метод значно швидший на всіх рівнях розподілу прогонів з max (setDF) <min (split), і attr
метод, як правило, більш ніж удвічі швидший.
Четвертий метод - крайній чемпіон, який є простим вкладеним lapply
, повертаючи вкладений список. Цей метод ілюструє вартість побудови data.frame зі списку. Більше того, всі методи, які я намагався з data.frame
функцією, були приблизно на порядок повільнішими, ніж data.table
методи.
дані
dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
split
кожного елементаdata.frame with 1 rows and N columns
замість ньогоlist of length N