2013-09-06 4 views
5

Also, ich habe viele data.tables Ich möchte in eine einzige data.table ohne doppelte Zeilen kombinieren. Der 'naive' Weg, dies zu tun ist, einen rbind Anruf mit Unique: unique(do.call(rbind, list.of.tables))Ersatz für unique (rbind()) bei der Verwendung von data.tables

Einpacken Dies funktioniert sicherlich, aber es ist ziemlich langsam. In meinem realen Fall haben die Tabellen zwei Spalten; eine Hash-Zeichenfolge und eine Größe. An diesem Punkt im Code sind sie nicht belegt. Ich habe zuerst mit Hashing getastet, aber der Gewinn beim Kombinieren wird durch die Zeit bis zur Taste ausgeglichen.

Hier ist, wie ich diese Optionen gebenchmarkt:

require(data.table) 

makeHash <- function(numberOfHashes) { 

    hashspace <- c(0:9, sapply(97:122, function(x) rawToChar(as.raw(x)))) 
    replicate(numberOfHashes, paste(sample(hashspace, 16), collapse="")) 

} 

mergeNoKey <- function(tableLength, modCount=tableLength/2) { 

    A <- B <- data.table(hash=makeHash(tableLength), size=sample(1:(1024^2), tableLength)) 

    A[1:modCount] <- data.table(hash=makeHash(modCount), size=sample(1:(1024^2), modCount)) 

    C <- unique(rbind(A,B)) 
} 

mergeWithKey <- function(tableLength, modCount=tableLength/2) { 

    A <- B <- data.table(hash=makeHash(tableLength), size=sample(1:(1024^2), tableLength)) 

    A[1:modCount] <- data.table(hash=makeHash(modCount), size=sample(1:(1024^2), modCount)) 

    setkey(A, hash) 
    setkey(B, hash) 

    C <- unique(rbind(A,B)) 
} 

require(microbenchmark) 
m <- microbenchmark(mergeNoKey(1000), mergeWithKey(1000), times=10) 
plot(m) 

Ich habe gespielt um mit tableLength und Zeiten und keinen großen Unterschied in der Leistung gesehen. Ich habe das Gefühl, dass es eine datentechnischere Möglichkeit gibt, dies zu tun.

In der Praxis muss ich dies mit vielen data.tables tun, nicht zwei, also ist Skalierbarkeit sehr wichtig; Ich wollte nur den obigen Code einfach halten.

Vielen Dank im Voraus!

Antwort

5

Ich glaube, Sie rbindlist und unique.data.table ...

C <- unique(rbindlist(list(A , B))) 
+6

+1 Btw, 'unique' Gewinne' by' in v1.8.10 (auf CRAN) verwendet werden soll für mehr Flexibilität (dank Steve), und 'list()' kopiert nicht länger benannte Eingaben (wie in diesem Beispiel) in GNU R v3.1.0 (was v1.8.10 kennt und mag). –

+0

Wow, überrascht habe ich das vermisst. Ich bekomme einen bescheideneren Gewinn, als ich mir erhofft hatte; Gibt es keinen besseren Weg? – ClaytonJY

+1

@ClaytonJY nehmen Sie die 'rbinding' aus der Funktion und testen * nur * den Unterschied in' rbind' vs. 'rbindlist'. Ich denke, Sie werden die meiste Zeit anderswo in Ihren Funktionen verbringen. –

Verwandte Themen