Ich habe heute daran für einen data.frame (wirklich eine data.table) mit Millionen von Beobachtungen und 35 Spalten gearbeitet. Mein Ziel war es, eine Liste von data.frames (data.tables) mit jeweils einer einzelnen Zeile zurückzugeben. Das heißt, ich wollte jede Zeile in einen separaten data.frame aufteilen und diese in einer Liste speichern.
Hier sind zwei Methoden, die ich mir ausgedacht habe und die ungefähr dreimal schneller waren als split(dat, seq_len(nrow(dat)))
für diesen Datensatz. Im Folgenden vergleiche ich die drei Methoden mit einem Datensatz mit 7500 Zeilen und 5 Spalten ( Iris 50-mal wiederholt).
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
)
Dies kehrt zurück
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
Während die Unterschiede nicht so groß sind wie in meinem vorherigen Test, ist die gerade setDF
Methode auf allen Ebenen der Verteilung von Läufen mit max (setDF) <min (split) signifikant schneller und die attr
Methode ist normalerweise mehr als doppelt so schnell.
Eine vierte Methode ist der extreme Champion, der einfach verschachtelt lapply
ist und eine verschachtelte Liste zurückgibt. Diese Methode veranschaulicht die Kosten für die Erstellung eines data.frame aus einer Liste. Außerdem waren alle Methoden, die ich mit der data.frame
Funktion ausprobierte, ungefähr eine Größenordnung langsamer als die data.table
Techniken.
Daten
dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
split
jedes Elements Typdata.frame with 1 rows and N columns
anstelle vonlist of length N