2011-12-21 16 views
6

Ho colpito un muro cercando di unire un file di grandi dimensioni e uno più piccolo. Ho readmany altri post sulla gestione della memoria in R, e non sono stato in grado di trovare un metodo non estremo (vai 64bit, carica in un cluster, ecc.) Per risolverlo. Ho provato un po 'con il pacchetto bigmemory, ma non sono riuscito a trovare una soluzione. Ho pensato di provare qui prima di alzare le mani per la frustrazione.Big Merge/Gestione memoria

Il codice sto correndo è come qui sotto:

#rm(list=ls()) 
localtempdir<- "F:/Temp/" 
memory.limit(size=4095) 
[1] 4095 
    memory.size(max=TRUE) 
[1] 487.56 
gc() 
     used (Mb) gc trigger (Mb) max used (Mb) 
Ncells 170485 4.6  350000 9.4 350000 9.4 
Vcells 102975 0.8 52633376 401.6 62529185 477.1 

client_daily<-read.csv(paste(localtempdir,"client_daily.csv",sep=""),header=TRUE) 
object.size(client_daily) 
>130MB 

sbp_demos<-read.csv(paste(localtempdir,"sbp_demos",sep="")) 
object.size(demos) 
>0.16MB 
client_daily<-merge(client_daily,sbp_demos,by.x="OBID",by.y="OBID",all.x=TRUE) 
Error: cannot allocate vector of size 5.0 MB 

immagino che sto chiedendo ci sono modi intelligenti di tutto questo, che non implicano l'acquisto di nuovo hardware?

  1. Devo essere in grado di merge per creare un oggetto più grande.
  2. Avrò quindi bisogno di fare regressioni ecc con quell'oggetto più grande.

Devo rinunciare? Il grande pubblico dovrebbe essere in grado di aiutare a risolvere questo problema?

Qualsiasi consiglio molto apprezzato.

dettagli: R versione 2.13.1 (2011-07-08) Piattaforma: i386-pc-mingw32/i386 (32-bit) Intel core 2 Duo @ 2.33GHz, 3.48GB di RAM

+4

Hai visto il pacchetto 'data.table'? È * veloce * per grandi fusioni e, casualmente, potrebbe essere più efficiente in termini di memoria da avviare? – Chase

+0

Questo probabilmente non risolverà il tuo problema, ma qui puoi provare qualcosa. Se ci sono colonne in un set di dati che non è necessario: rimuoverli dopo aver letto i dati, eseguire un gc(), quindi provare di nuovo l'unione. Un'altra idea è quella di convertire i dati in una matrice, se possibile, poiché tendono a consumare meno memoria. – Rguy

risposta

8

Come già detto, puoi provare data.table o forse sqldf.

Per entrambi, si otterrà probabilmente più succo se si impostano gli indici in modo appropriato.

Con data.table si farebbe:

dt1 <- data.table(sbp_demos, key='OBID') 
dt2 <- data.table(client_daily, key='OBID') 

## Do an INNER JOIN-like operation, where non-matching rows are removed 
mi <- dt1[dt2, nomatch=0] 

## Do a RIGHT JOIN(?)-like operation ... all rows in dt2 will be returned. 
## If there is no matching row in dt1, the values in the dt1 columns for 
## the merged row will be NA 
mr <- dt1[dt2] 

Se si va al sqldf percorso, look at example 4i on its website ... ancora una volta, assicurarsi di utilizzare correttamente gli indici.