2011-12-21 15 views
6

Uderzyłem w ścianę próbując scalić duży plik i mniejszy. Mam też inne posty dotyczące zarządzania pamięcią w R i nie byłem w stanie znaleźć metody nie-skrajnej (przejdź do 64-bitów, wgrywaj do klastra, itp.), Aby go rozwiązać. Próbowałem trochę z pakietem bigmemory, ale nie byłem w stanie znaleźć rozwiązania. Myślałem, że spróbuję tutaj, zanim podniosę ręce z frustracji.Big Merge/Zarządzanie pamięcią

Kod biegnę jest jak poniżej:

#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 

Chyba pytam czy są jakieś sprytne sposoby obejścia tego, które nie wiążą się z zakupem nowego sprzętu?

  1. Muszę być w stanie merge stworzyć większy obiekt.
  2. Będę wtedy musiał robić regresje itp. Z tym większym obiektem.

Czy powinienem zrezygnować? Czy bigmemory będą w stanie pomóc rozwiązać ten problem?

Wszelkie wskazówki są mile widziane.

Szczegóły: R w wersji 2.13.1 (2011-07-08) Platforma: i386-pc-mingw32/i386 (32-bit) Intel Rdzeń 2 Duo @ 2.33GHz, 3.48GB RAM

+4

Czy obejrzałeś pakiet 'data.table'? Jest * szybki * dla dużych scaleń, i przypadkowo może być bardziej efektywny pod względem pamięci do rozruchu? – Chase

+0

Prawdopodobnie nie rozwiąże to problemu, ale możesz spróbować. Jeśli są jakieś kolumny w zbiorze danych, których nie potrzebujesz: usuń je po odczytaniu danych, wykonaj polecenie gc(), a następnie spróbuj ponownie scalić. Innym pomysłem jest przekształcenie danych na matrycę, o ile to możliwe, ponieważ zużywają one mniej pamięci. – Rguy

Odpowiedz

8

Jak już wspomniano Chase, możesz wypróbować data.table lub może sqldf.

W przypadku jednego z nich prawdopodobnie uzyskasz więcej soku, jeśli odpowiednio ustawisz indeksy.

Z data.table byś:

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] 

Jeśli jedziesz, tym sqldf trasa, look at example 4i on its website ... ponownie, upewnij się poprawnie używać indeksów.