2012-06-21 11 views
23

Ich bin auf der Suche nach einer effizienten (sowohl computerressourcebezogenen als auch lernenden/implementierenden) Methode, um zwei größere (Größe> 1 Million/300 KB RData Datei) Datenrahmen zusammenzuführen.Effiziente Alternativen zum Zusammenführen für größere data.frames R

"Merge" in der Basis R und "Join" in Plyr scheinen alle meine Speicher verbrauchen effektiv mein System zusammenbrechen.

Beispiel
Last test data frame

und versuchen

test.merged<-merge(test, test) 

oder

test.merged<-join(test, test, type="all") 
    -

Der folgende Beitrag liefert eine Liste der Zusammenführung und Alternativen:
How to join (merge) data frames (inner, outer, left, right)?

Die folgende erlaubt Prüfobjekt Größe:
https://heuristically.wordpress.com/2010/01/04/r-memory-usage-statistics-variable/

produzierten Daten von anonym

+8

sql.df oder data.table? –

+0

Nach dem Ausnehmen der netten Antworten unten, konnte ich finden: http://stackoverflow.com/questions/4322219/whats-the-fastest-way-to-merge-join-data-frames-in-r (obwohl die Frage war nicht über große df, sondern über das Speichern von Millisekunden, bekam es ähnliche Antworten wie unten). –

Antwort

18

Hier ist das obligatorische data.table Beispiel:

library(data.table) 

## Fix up your example data.frame so that the columns aren't all factors 
## (not necessary, but shows that data.table can now use numeric columns as keys) 
cols <- c(1:5, 7:10) 
test[cols] <- lapply(cols, FUN=function(X) as.numeric(as.character(test[[X]]))) 
test[11] <- as.logical(test[[11]]) 

## Create two data.tables with which to demonstrate a data.table merge 
dt <- data.table(test, key=names(test)) 
dt2 <- copy(dt) 
## Add to each one a unique non-keyed column 
dt$X <- seq_len(nrow(dt)) 
dt2$Y <- rev(seq_len(nrow(dt))) 

## Merge them based on the keyed columns (in both cases, all but the last) to ... 
## (1) create a new data.table 
dt3 <- dt[dt2] 
## (2) or (poss. minimizing memory usage), just add column Y from dt2 to dt 
dt[dt2,Y:=Y] 
+0

Danke für die tolle Antwort. Ich denke, wenn Sie möchten, dass die ursprüngliche Reihenfolge beibehalten wird, fügen Sie eine 1: grow (df) -Spalte hinzu und verwenden Sie sie als das erste Element des Schlüssels? –

+0

@ EtienneLow-Décarie - Das ist eine gute Frage. Ich denke, dass Sie eine solche Spalte hinzufügen möchten, aber ** machen Sie es nicht zu einem Element des Schlüssels. Auf diese Weise können Sie die Daten jederzeit neu anordnen. (Es sollte nicht Teil des Schlüssels sein, da es nur eine Auftragsmarkierung ist, keine Variable/Gruppenkennung, die in verschiedenen Datensätzen die gleiche Bedeutung hat). –

+2

Macht data.table das Ende der Notwendigkeit für anwenden und plyr! Ziemlich beeindruckend! –

0

Müssen Sie die Zusammenführung tun in R? Wenn nicht, füge die zugrunde liegenden Datendateien mit einer einfachen Dateiverkettung zusammen und lade sie dann in R. (Ich weiß, dass dies möglicherweise nicht auf deine Situation zutrifft - aber wenn dies der Fall ist, könnte es dir Kopfschmerzen ersparen.)

+2

Es muss live in R gemacht werden, da es ein Schritt in einer Optimierungsroutine ist, die auf die Festplatte schreiben würde, wäre wahrscheinlich ein Flaschenhals. Trotzdem danke. –

20

Hier sind einige Zeitpunkte für die data.table vs. data.frame Methoden.
Die Verwendung von data.table ist sehr viel schneller. Bezüglich des Gedächtnisses kann ich informell berichten, dass die beiden Methoden im RAM-Bereich sehr ähnlich sind (innerhalb von 20%).

library(data.table) 

set.seed(1234) 
n = 1e6 

data_frame_1 = data.frame(id=paste("id_", 1:n, sep=""), 
          factor1=sample(c("A", "B", "C"), n, replace=TRUE)) 
data_frame_2 = data.frame(id=sample(data_frame_1$id), 
          value1=rnorm(n)) 

data_table_1 = data.table(data_frame_1, key="id") 
data_table_2 = data.table(data_frame_2, key="id") 

system.time(df.merged <- merge(data_frame_1, data_frame_2)) 
# user system elapsed 
# 17.983 0.189 18.063 


system.time(dt.merged <- merge(data_table_1, data_table_2)) 
# user system elapsed 
# 0.729 0.099 0.821 
Verwandte Themen