rbindlistes 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 rbindlistestá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.framehace 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), rbindlistno 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
rbindlistpuede manejar lists data.framesy 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 rbindlistse implementa en C, por lo que es eficiente en memoria, se utiliza setattrpara establecer atributos por referencia
rbind.data.framese 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.frametiene una lógica especial de "secuestro": cuando su primer argumento es adata.table, llama en su.rbind.data.tablelugar, lo que hace una pequeña comprobación y luego llamarbindlistinternamente. Entonces, si ya tienedata.tableobjetos para vincular, probablemente haya poca diferencia de rendimiento entrerbindyrbindlist.rbindlistes 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_listtambién es bastante similarPor
v1.9.2,rbindlisthabía evolucionado bastante, implementando muchas características que incluyen:Además, en
v1.9.2,rbind.data.tabletambién ganó unfillargumento, 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.framese 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.frametambié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
rbindlistfalta (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
rbindlistlause.namesfunció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_rowsLa 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
dplyrla versión de.fuente