Por v1.9.2
, rbindlist
había evolucionado bastante, implementando muchas características que incluyen:
- Elección de la
SEXPTYPE
columna más alta mientras se vincula: implementado al v1.9.2
cerrar FR # 2456 y Bug # 4981 .
- Manejo de
factor
columnas correctamente: primero se implementó al v1.8.10
cerrar el Bug # 2650 y se extendió también a los factores ordenados vinculantes v1.9.2
, cerrando FR # 4856 y Bug # 5019 .
Además, en v1.9.2
, rbind.data.table
también ganó un fill
argumento, que permite enlazar rellenando columnas faltantes, implementado en R.
Ahora v1.9.3
, hay aún más mejoras en estas características existentes:
rbindlist
gana un argumento use.names
, que por defecto es FALSE
para compatibilidad con versiones anteriores.
rbindlist
también gana un argumento fill
, que por defecto también es FALSE
para compatibilidad con versiones anteriores.
- Todas estas características se implementan en C y se escriben cuidadosamente para no comprometer la velocidad al agregar funcionalidades.
- Ya
rbindlist
que ahora puede coincidir por nombres y llenar columnas faltantes, rbind.data.table
solo llama rbindlist
ahora. La única diferencia es que, use.names=TRUE
por defecto rbind.data.table
, para compatibilidad con versiones anteriores.
rbind.data.frame
se ralentiza bastante debido principalmente a las copias (que @mnel también señala) que podrían evitarse (moviéndose a C). Creo que esa no es la única razón. La implementación para verificar / hacer coincidir los nombres de columna rbind.data.frame
también podría ser más lenta cuando hay muchas columnas por data.frame y hay muchos data.frames para vincular (como se muestra en el punto de referencia a continuación).
Sin embargo, esa rbindlist
falta (ed) de ciertas características (como verificar niveles de factores o nombres coincidentes) tiene un peso muy pequeño (o nulo) para que sea más rápido rbind.data.frame
. Se debe a que se implementaron cuidadosamente en C, optimizados para la velocidad y la memoria.
Aquí hay un punto de referencia que resalta el enlace eficiente al tiempo que coincide con los nombres de columna, así como con rbindlist
la use.names
función de v1.9.3
. El conjunto de datos consta de 10000 data.frames cada uno de tamaño 10 * 500.
Nota: este punto de referencia ha sido actualizado para incluir una comparación con dplyr
'sbind_rows
library(data.table) # 1.11.5, 2018-06-02 00:09:06 UTC
library(dplyr) # 0.7.5.9000, 2018-06-12 01:41:40 UTC
set.seed(1L)
names = paste0("V", 1:500)
cols = 500L
foo <- function() {
data = as.data.frame(setDT(lapply(1:cols, function(x) sample(10))))
setnames(data, sample(names))
}
n = 10e3L
ll = vector("list", n)
for (i in 1:n) {
.Call("Csetlistelt", ll, i, foo())
}
system.time(ans1 <- rbindlist(ll))
# user system elapsed
# 1.226 0.070 1.296
system.time(ans2 <- rbindlist(ll, use.names=TRUE))
# user system elapsed
# 2.635 0.129 2.772
system.time(ans3 <- do.call("rbind", ll))
# user system elapsed
# 36.932 1.628 38.594
system.time(ans4 <- bind_rows(ll))
# user system elapsed
# 48.754 0.384 49.224
identical(ans2, setDT(ans3))
# [1] TRUE
identical(ans2, setDT(ans4))
# [1] TRUE
La vinculación de columnas como tal sin verificar los nombres tomó solo 1.3, mientras que la verificación de los nombres de columnas y la vinculación de manera adecuada solo tomó 1.5 segundos más. En comparación con la solución base, es 14 veces más rápido y 18 veces más rápido que dplyr
la versión de.
attr<-
,class<-
y (creo)rownames<-
todos modifican en su lugar.