Domanda

Ho due dati fotogrammi df1 e df2 che ogni hanno circa 10 milioni di righe e 4 colonne. Li ho letti in R utilizzando RODBC / sqlquery senza problemi, ma quando provo a rbind loro, ottengo che più temuto dei messaggi di errore R: cannot allocate memory. Ci hanno avuto modo di essere modi più efficienti per fare un rbind in modo più efficiente - chiunque hanno i loro trucchi preferiti su questo vogliono condividere? Per esempio ho trovato questo esempio nel documento per sqldf:

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

E 'questo il modo migliore / consigliato di farlo?

UPDATE Ho preso al lavoro utilizzando l'argomento cruciale dbname = tempfile() nella chiamata sqldf sopra, come suggerisce JD lungo nella sua risposta al questa domanda

È stato utile?

Soluzione

Piuttosto che leggere nella R all'inizio e poi combinandoli si potrebbe avere SQLite leggerli e combinarle prima di inviarli al R. In questo modo i file non vengono mai caricati singolarmente in 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())

In questo modo:

>  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

Questa versione più corta funziona anche se l'ordine di fila non è importante:

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

Visualizza la pagina iniziale sqldf http://sqldf.googlecode.com e ?sqldf per maggiori informazioni. Prestare particolare attenzione agli argomenti di formato di file in quanto sono vicini ma non identico a read.table. Qui abbiamo utilizzato i valori di default così è stato meno di un problema.

Altri suggerimenti

Avviso il pacchetto data.table R per operazioni efficienti su oggetti con oltre parecchi milioni di dischi.

La versione 1.8.2 di ciò che offre la funzione di pacchetti rbindlist attraverso il quale è possibile ottenere quello che vuoi in modo molto efficiente. Così, invece di rbind(a5r, a6r) è possibile:

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

Cerca di creare una data.frame di dimensione desiderata, quindi importare i dati utilizzando gli indici.

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

credo che rbind cresce oggetto senza pre-allocare le sue dimensioni ... Non sono sicuro che positivamente, questa è solo una supposizione. Mi pettino down "L'Inferno R" o "manipolazione dei dati con R" stasera. Forse merge farà il trucco ...

Modifica

E si dovrebbe nudo in mente che (forse) il sistema e / o R non possono far fronte con qualcosa di così grande. Prova RevolutionR, forse riuscirete a risparmiare qualche tempo / risorse.

Per completezza in questa discussione sul tema dell'unione: ing file di grandi dimensioni, provare a utilizzare i comandi della shell sui file di combinarli. In Windows che viene comando "Copia" con la bandiera "/ B". Esempio:

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

richiede che i file non hanno intestazione, e lo stesso delimitatore etc etc. La velocità e la versatilità dei comandi di shell a volte è un grande vantaggio, in modo da non dimenticate CLI-comandi quando mappatura flussi di dati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top