2013-09-06 3 views
5

Quindi, ho molti dati.tables che desidero combinare in un singolo data.table senza righe duplicate. Il modo "ingenuo" per fare ciò è di racchiudere una chiamata rbind con univoco: unique(do.call(rbind, list.of.tables))Sostituzione per unique (rbind()) durante l'utilizzo di data.tables

Questo funziona sicuramente, ma è piuttosto lento. Nel mio caso reale le tabelle hanno due colonne; una stringa e una dimensione hash. A questo punto del codice, non sono codificati. Ho giocato prima con il keying di hash, ma il guadagno nella combinazione è compensato dal time to key.

Ecco come lo benchmark queste opzioni:

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) 

Ho giocato in giro con tableLength e volte e visto nessuna grande differenza in termini di prestazioni. Mi sento come se ci fosse un modo più semplice di data.table-ish per farlo.

In pratica ho bisogno di farlo con molti data.tables, non due, quindi la scalabilità è molto importante; Volevo solo mantenere il codice sopra semplice.

Grazie in anticipo!

risposta

5

Penso che si desidera utilizzare rbindlist e unique.data.table ...

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

+1 Btw, '' guadagni unique' by' a v1.8.10 (su CRAN) per una maggiore flessibilità (grazie a Steve), e 'list()' non copia più gli input con nome (come in questo esempio) in GNU R v3.1.0 (che v1.8.10 conosce e piace). –

+0

Wow, sorpreso mi è mancato. Sto ottenendo un guadagno più modesto di quanto speravo; non c'è modo migliore? – ClaytonJY

+1

@ClaytonJY toglie 'rbinding' dalla funzione e prova * solo * la differenza in' rbind' contro 'rbindlist'. Penso che troverai che la maggior parte del tempo viene spesa altrove nelle tue funzioni. –