Trabajé en esto hoy para un data.frame (realmente un data.table) con millones de observaciones y 35 columnas. Mi objetivo era devolver una lista de data.frames (data.tables) cada uno con una sola fila. Es decir, quería dividir cada fila en un marco de datos independiente y almacenarlos en una lista.
Aquí hay dos métodos que se me ocurrieron que fueron aproximadamente 3 veces más rápidos que split(dat, seq_len(nrow(dat)))
para ese conjunto de datos. A continuación, comparo los tres métodos en un conjunto de datos de 7500 filas y 5 columnas ( iris repetido 50 veces).
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
)
Esto vuelve
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
Si bien las diferencias no son tan grandes como en mi prueba anterior, el setDF
método directo es significativamente más rápido en todos los niveles de distribución de ejecuciones con max (setDF) <min (split) y el attr
método suele ser más del doble de rápido.
Un cuarto método es el campeón extremo, que es un simple anidado lapply
, que devuelve una lista anidada. Este método ejemplifica el costo de construir un data.frame a partir de una lista. Además, todos los métodos que probé con la data.frame
función fueron aproximadamente un orden de magnitud más lentos que las data.table
técnicas.
datos
dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
split
cada elemento tiene tipo endata.frame with 1 rows and N columns
lugar delist of length N