rbindlist
es una versión optimizada de do.call(rbind, list(...))
, que es conocida por ser lenta cuando se usarbind.data.frame
¿Dónde realmente sobresale?
Algunas preguntas que muestran dónde rbindlist
están los brillos
Rápida fusión vectorizada de la lista de datos. Marcos por fila
Problemas para convertir una larga lista de data.frames (~ 1 millón) en un solo data.frame usando do.call y ldply
Estos tienen puntos de referencia que muestran lo rápido que puede ser.
rbind.data.frame es lento, por una razón
rbind.data.frame
hace muchas comprobaciones y coincidirá por nombre. (es decir, rbind.data.frame tendrá en cuenta el hecho de que las columnas pueden estar en diferentes órdenes y coincidir por nombre), rbindlist
no realiza este tipo de comprobación y se unirá por posición
p.ej
do.call(rbind, list(data.frame(a = 1:2, b = 2:3), data.frame(b = 1:2, a = 2:3)))
## a b
## 1 1 2
## 2 2 3
## 3 2 1
## 4 3 2
rbindlist(list(data.frame(a = 1:5, b = 2:6), data.frame(b = 1:5, a = 2:6)))
## a b
## 1: 1 2
## 2: 2 3
## 3: 1 2
## 4: 2 3
Algunas otras limitaciones de rbindlist
Se utiliza para luchar para hacer frente factors
, debido a un error que desde entonces ha sido fijada:
rbindlist dos data.tables donde uno tiene factor y otro tiene tipo de carácter para una columna ( Bug # 2650 )
Tiene problemas con nombres de columna duplicados.
vea
Mensaje de advertencia: en rbindlist (allargs): NAs introducidos por coerción: ¿posible error en data.table? ( Error # 2384 )
Los nombres de fila de rbind.data.frame pueden ser frustrantes
rbindlist
puede manejar lists
data.frames
y data.tables
, y devolverá un data.table sin nombres de fila
puedes meterte en una confusión de nombres de fila usando do.call(rbind, list(...))
ver
¿Cómo evitar el cambio de nombre de las filas cuando se usa rbind dentro de do.call?
Eficiencia de la memoria
En términos de memoria rbindlist
se implementa en C
, por lo que es eficiente en memoria, se utiliza setattr
para establecer atributos por referencia
rbind.data.frame
se implementa en R
, realiza muchas asignaciones y utiliza attr<-
( class<-
y rownames<-
todo lo cual (internamente) creará copias de la data.frame creada.
attr<-
,class<-
y (creo)rownames<-
todos modifican en su lugar.DF = data.frame(a=1:3); .Internal(inspect(DF)); tracemem(DF); attr(DF,"test") <- "hello"; .Internal(inspect(DF))
.rbind.data.frame
tiene una lógica especial de "secuestro": cuando su primer argumento es adata.table
, llama en su.rbind.data.table
lugar, lo que hace una pequeña comprobación y luego llamarbindlist
internamente. Entonces, si ya tienedata.table
objetos para vincular, probablemente haya poca diferencia de rendimiento entrerbind
yrbindlist
.rbindlist
es capaz de coincidir por nombres (use.names=TRUE
) y también llenar las columnas que faltan (fill=TRUE
). He actualizado esto , esto y esta publicación. ¿Te importa editar este o está bien si lo hago? De cualquier manera está bien para mí.dplyr::rbind_list
también es bastante similarPor
v1.9.2
,rbindlist
había evolucionado bastante, implementando muchas características que incluyen:Además, en
v1.9.2
,rbind.data.table
también ganó unfill
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: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 columnarbind.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ápidorbind.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
lause.names
función dev1.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
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.fuente