Tengo un código que en un lugar termina con una lista de marcos de datos que realmente quiero convertir en un solo marco de datos grandes.
Recibí algunos consejos de una pregunta anterior que intentaba hacer algo similar pero más complejo.
Aquí hay un ejemplo de lo que estoy comenzando (esto se simplifica enormemente para la ilustración):
listOfDataFrames <- vector(mode = "list", length = 100)
for (i in 1:100) {
listOfDataFrames[[i]] <- data.frame(a=sample(letters, 500, rep=T),
b=rnorm(500), c=rnorm(500))
}
Actualmente estoy usando esto:
df <- do.call("rbind", listOfDataFrames)
do.call("rbind", list)
idioma es lo que he usado antes también. ¿Por qué necesitas la inicialunlist
?Respuestas:
Use bind_rows () del paquete dplyr:
fuente
.id = "column_label"
agrega los nombres de fila únicos basados en los nombres de elementos de la lista.dplyr
Como es 2018 y es una herramienta rápida y sólida de usar, he cambiado esto a la respuesta aceptada. ¡Los años pasan volando!Otra opción es usar una función plyr:
Esto es un poco más lento que el original:
Supongo que usar
do.call("rbind", ...)
será el enfoque más rápido que encontrará a menos que pueda hacer algo como (a) usar matrices en lugar de data.frames y (b) preasignar la matriz final y asignarla en lugar de hacerla crecer .Editar 1 :
Basado en el comentario de Hadley, aquí está la última versión de
rbind.fill
CRAN:Esto es más fácil que rbind y marginalmente más rápido (estos tiempos se mantienen en varias ejecuciones). Y hasta donde yo entiendo, la versión de
plyr
on github es aún más rápida que esto.fuente
I()
podría reemplazardata.frame
en suldply
llamadamelt.list
en remodelación (2)do.call(function(...) rbind(..., make.row.names=F), df)
es útil si no desea los nombres de fila únicos generados automáticamente.Con el fin de completar, pensé que las respuestas a esta pregunta requerían una actualización. "Supongo que usar
do.call("rbind", ...)
será el enfoque más rápido que encontrará ..." Probablemente fue cierto para mayo de 2010 y algún tiempo después, pero aproximadamente en septiembre de 2011rbindlist
se introdujo una nueva función en ladata.table
versión de paquete 1.8.2 , con un comentario que dice "Esto hace lo mismodo.call("rbind",l)
pero mucho más rápido". ¿Cuanto más rápido?fuente
ldply
un montón de marcos de datos largos y fundidos. De todos modos, obtuve una aceleración increíble al usar surbindlist
sugerencia.dplyr::rbind_all(listOfDataFrames)
también hará el truco.rbindlist
pero que agregue los marcos de datos por columna? algo así como una lista de cbindlist?do.call()
había estado corriendo en una lista de marcos de datos durante 18 horas, y aún no había terminado, ¡¡¡gracias !!!Código:
Sesión:
ACTUALIZACIÓN : Vuelve a ejecutar el 31 de enero de 2018. Corrió en la misma computadora. Nuevas versiones de paquetes. Semillas añadidas para los amantes de las semillas.
ACTUALIZACIÓN : Vuelva a ejecutar 06-ago-2019.
fuente
set.seed
) pero vi algunas diferencias en el peor de los casos.rbindlist
en realidadTambién hay
bind_rows(x, ...)
endplyr
.fuente
Aquí hay otra forma de hacerlo (simplemente agregándolo a las respuestas porque
reduce
es una herramienta funcional muy efectiva que a menudo se pasa por alto como un reemplazo para los bucles. En este caso particular, ninguno de estos es significativamente más rápido que do.call)utilizando la base R:
o, usando el tidyverse:
fuente
Cómo se debe hacer en el tidyverse:
fuente
map
sibind_rows
puede tomar una lista de marcos de datos?Una imagen actualizada para aquellos que quieran comparar algunas de las respuestas recientes (quería comparar la solución de ronroneo a dplyr). Básicamente combiné respuestas de @TheVTM y @rmf.
Código:
Información de la sesión:
Versiones de paquete:
fuente
Lo único que
data.table
faltan las soluciones es la columna de identificador para saber de qué marco de datos en la lista provienen los datos.Algo como esto:
El
idcol
parámetro agrega una columna (.id
) que identifica el origen del marco de datos contenido en la lista. El resultado sería algo como esto:fuente