¿Cómo puedo evitar que rbind () se vuelva realmente lento a medida que el dataframe crezca?

Tengo un dataframe con solo 1 fila. Para esto, empiezo a agregar filas usando rbind

df #mydataframe with only one row for (i in 1:20000) { df<- rbind(df, newrow) } 

esto se vuelve muy lento a medida que crece. ¿Porqué es eso? y ¿cómo puedo hacer que este tipo de código sea más rápido?

Estás en el segundo círculo del infierno , es decir, no asignar previamente las estructuras de datos.

Hacer crecer objetos de esta manera es algo muy muy malo en R. O pre-asignar e insertar:

 df < - data.frame(x = rep(NA,20000),y = rep(NA,20000)) 

o reestructurar su código para evitar este tipo de adición incremental de filas. Como se discutió en el enlace que cito, la razón de la lentitud es que cada vez que agrega una fila, R necesita encontrar un nuevo bloque contiguo de memoria para encajar en el dataframe. Mucho o no se copia.

Intenté un ejemplo. Por lo que vale, está de acuerdo con la afirmación del usuario de que insertar filas en el dataframe también es muy lento. No entiendo muy bien lo que está sucediendo, ya que esperaba que el problema de asignación superara la velocidad de copiado. ¿Alguien puede replicar esto o explicar por qué los resultados a continuación (rbind

editar : la primera vez olvidé inicializar el objeto en hell2fun en un dataframe, por lo que el código estaba haciendo operaciones matriciales en lugar de operaciones de marcos de datos, que son mucho más rápidas. Si tengo la oportunidad, ampliaré la comparación al dataframe frente a la matriz. Las aserciones cualitativas en el primer párrafo se mantienen, sin embargo.

 N < - 1000 set.seed(101) r <- matrix(runif(2*N),ncol=2) ## second circle of hell hell2fun <- function() { df <- as.data.frame(rbind(r[1,])) ## initialize for (i in 2:N) { df <- rbind(df,r[i,]) } } insertfun <- function() { df <- data.frame(x=rep(NA,N),y=rep(NA,N)) for (i in 1:N) { df[i,] <- r[i,] } } rsplit <- as.list(as.data.frame(t(r))) rbindfun <- function() { do.call(rbind,rsplit) } library(rbenchmark) benchmark(hell2fun(),insertfun(),rbindfun()) ## test replications elapsed relative user.self ## 1 hell2fun() 100 32.439 484.164 31.778 ## 2 insertfun() 100 45.486 678.896 42.978 ## 3 rbindfun() 100 0.067 1.000 0.076