ticks mtext ggplot r memory memory-management data.table sqldf

mtext - R: cómo enlazar dos enormes marcos de datos sin quedarse sin memoria



text in r (4)

Tengo dos marcos de datos df1 y df2 que tienen cada uno alrededor de 10 millones de filas y 4 columnas. Los leí en R usando RODBC / sqlQuery sin problemas, pero cuando intento rbind , recibo la más temida de los mensajes de error de R: cannot allocate memory . Tiene que haber maneras más eficientes de hacer un rbind más eficiente: ¿alguien tiene sus trucos favoritos sobre esto que quiere compartir? Por ejemplo, encontré este ejemplo en el documento para sqldf :

# rbind a7r <- rbind(a5r, a6r) a7s <- sqldf("select * from a5s union all select * from a6s")

¿Es esa la forma mejor / recomendada de hacerlo?

ACTUALIZACIÓN Lo hice funcionar usando el crucial dbname = tempfile() en la llamada sqldf anterior, como sugiere JD Long en su respuesta a esta pregunta


En lugar de leerlos en R al principio y luego combinarlos, puede hacer que SQLite los lea y los combine antes de enviarlos a R. De esta manera, los archivos nunca se cargan individualmente en R.

# create two sample files DF1 <- data.frame(A = 1:2, B = 2:3) write.table(DF1, "data1.dat", sep = ",", quote = FALSE) rm(DF1) DF2 <- data.frame(A = 10:11, B = 12:13) write.table(DF2, "data2.dat", sep = ",", quote = FALSE) rm(DF2) # now we do the real work library(sqldf) data1 <- file("data1.dat") data2 <- file("data2.dat") sqldf(c("select * from data1", "insert into data1 select * from data2", "select * from data1"), dbname = tempfile())

Esto da:

> sqldf(c("select * from data1", "insert into data1 select * from data2", "select * from data1"), dbname = tempfile()) A B 1 1 2 2 2 3 3 10 12 4 11 13

Esta versión más corta también funciona si el orden de las filas no es importante:

sqldf("select * from data1 union select * from data2", dbname = tempfile())

Consulte la página de inicio de sqldf http://sqldf.googlecode.com y ?sqldf para obtener más información. Preste especial atención a los argumentos de formato de archivo, ya que están cerca pero no son idénticos a read.table . Aquí hemos utilizado los valores predeterminados por lo que fue un problema menor.


Intente crear un data.frame de data.frame del tamaño deseado, por lo tanto, importe sus datos utilizando subíndices.

dtf <- as.data.frame(matrix(NA, 10, 10)) dtf1 <- as.data.frame(matrix(1:50, 5, 10, byrow=TRUE)) dtf2 <- as.data.frame(matrix(51:100, 5, 10, byrow=TRUE)) dtf[1:5, ] <- dtf1 dtf[6:10, ] <- dtf2

Supongo que rbind crecer el objeto sin asignar previamente sus dimensiones ... No estoy seguro de que esto sea solo una suposición. Voy a peinar hacia abajo "The R Inferno" o "Data Manipulation with R" esta noche. Tal vez la merge hará el truco ...

EDITAR

Y debe tener en cuenta que (tal vez) su sistema y / o R no pueden hacer frente a algo tan grande. Prueba RevolutionR, quizás puedas ahorrar algo de tiempo / recursos.


Observe el paquete data.table R para operaciones eficientes en objetos con más de varios millones de registros.

La versión 1.8.2 de ese paquete ofrece la función rbindlist través de la cual puede lograr lo que quiere de manera muy eficiente. Por lo tanto, en lugar de rbind(a5r, a6r) puedes:

library(data.table) rbindlist(list(a5r, a6r))


Para completar este hilo en el tema de la unión: ingiriendo archivos grandes, intente usar comandos de shell en los archivos para combinarlos. En las ventanas es el comando "COPIAR" con el indicador "/ B". Ejemplo:

system(command = paste0( c("cmd.exe /c COPY /Y" , ''"file_1.csv" /B'' , ''+ "file_2.csv" /B'' , ''"resulting_file.csv" /B'' ), collapse = " " ) )#system

Requiere que los archivos no tengan encabezado, el mismo delimitador, etc. La velocidad y la versatilidad de los comandos de shell a veces son un gran beneficio, así que no olvide los comandos CLI al asignar flujos de datos.