with how funcion different dataframes data concatenate columns column bind_rows r dataframe rbind

how - merge columns in r



¿Alternativa de memoria eficiente a rbind-rbind en el lugar? (4)

Ahora mismo resolví la siguiente solución:

nextrow = nrow(df)+1 df[nextrow:(nextrow+nrow(df.extension)-1),] = df.extension # we need to assure unique row names row.names(df) = 1:nrow(df)

Ahora no me quedo sin memoria. Creo que es porque yo almaceno

object.size(df) + 2 * object.size(df.extension)

mientras que con rbind R necesitaría

object.size(rbind(df,df.extension)) + object.size(df) + object.size(df.extension).

Después de eso uso

rm(df.extension) gc(reset=TRUE)

para liberar la memoria que ya no necesito.

Esto solucionó mi problema por ahora, pero creo que hay una forma más avanzada de hacer un rbind de memoria eficiente. Agradezco cualquier comentario sobre esta solución.

Necesito encontrar dos marcos de datos grandes. En este momento yo uso

df <- rbind(df, df.extension)

pero yo (casi) instantáneamente me quedo sin memoria. Supongo que es porque df se guarda en la memoria dos veces. Es posible que vea marcos de datos aún más grandes en el futuro, así que necesito algún tipo de entorno in situ.

Entonces mi pregunta es: ¿hay alguna manera de evitar la duplicación de datos en la memoria cuando se usa rbind?

Encontré esta question , que usa SqlLite, pero realmente quiero evitar usar el disco duro como un caché.


Antes que nada: usa la solución de la otra pregunta a la que te diriges si quieres estar seguro. Como R es call-by-value, olvídese de un método "in-situ" que no copie sus dataframes en la memoria.

Un método no recomendable para guardar bastante memoria es pretender que sus dataframes son listas, forzar una lista usando for-loop (aplicar se comerá la memoria como el infierno) y hacer que R crea que en realidad es un dataframe.

Te lo advertiré de nuevo: usar esto en marcos de datos más complejos es buscar problemas y errores difíciles de encontrar. Así que asegúrese de probar lo suficientemente bien, y si es posible, evite esto tanto como sea posible.

Puede intentar seguir el siguiente enfoque:

n1 <- 1000000 n2 <- 1000000 ncols <- 20 dtf1 <- as.data.frame(matrix(sample(n1*ncols), n1, ncols)) dtf2 <- as.data.frame(matrix(sample(n2*ncols), n1, ncols)) dtf <- list() for(i in names(dtf1)){ dtf[[i]] <- c(dtf1[[i]],dtf2[[i]]) } attr(dtf,"row.names") <- 1:(n1+n2) attr(dtf,"class") <- "data.frame"

Borra los nombres de las filas que realmente tenías (puedes reconstruirlos, pero verifica si hay nombres de fila duplicados). Tampoco lleva a cabo todas las otras pruebas incluidas en rbind.

Le ahorra aproximadamente la mitad de la memoria en mis pruebas, y en mi prueba tanto el dtfcomb como el dtf son iguales. El recuadro rojo es rbind, el amarillo es mi enfoque basado en listas.

Secuencia de comandos de prueba:

n1 <- 3000000 n2 <- 3000000 ncols <- 20 dtf1 <- as.data.frame(matrix(sample(n1*ncols), n1, ncols)) dtf2 <- as.data.frame(matrix(sample(n2*ncols), n1, ncols)) gc() Sys.sleep(10) dtfcomb <- rbind(dtf1,dtf2) Sys.sleep(10) gc() Sys.sleep(10) rm(dtfcomb) gc() Sys.sleep(10) dtf <- list() for(i in names(dtf1)){ dtf[[i]] <- c(dtf1[[i]],dtf2[[i]]) } attr(dtf,"row.names") <- 1:(n1+n2) attr(dtf,"class") <- "data.frame" Sys.sleep(10) gc() Sys.sleep(10) rm(dtf) gc()


Este es un candidato perfecto para bigmemory . Vea el sitio para más información. Aquí hay tres aspectos de uso a considerar:

  1. Está bien utilizar HD: la asignación de memoria a HD es mucho más rápida que prácticamente cualquier otro acceso, por lo que es posible que no vea ninguna ralentización. A veces confío en> 1 TB de matrices mapeadas en memoria, aunque la mayoría tienen entre 6 y 50 GB. Además, como el objeto es una matriz, esto no requiere una sobrecarga real de código de reescritura para usar el objeto.
  2. Si usa una matriz con respaldo de archivos o no, puede usar separated = TRUE para separar las columnas. No he usado tanto, debido a mi tercer consejo:
  3. Puede sobreasignar el espacio de HD para permitir un tamaño de matriz potencialmente mayor, pero solo cargar la submatriz de interés. De esta manera no hay necesidad de hacer rbind .

Nota: Aunque la pregunta original dirigida a marcos de datos y bigmemory es adecuada para matrices, se pueden crear fácilmente matrices diferentes para diferentes tipos de datos y luego combinar los objetos en RAM para crear un marco de datos, si es realmente necesario.