2013-09-06 12 views
5

Mam wiele tabel danych, które chcę połączyć w jedną tabelę data.table bez duplikatów wierszy. "Naiwny" sposób, aby to zrobić, to owinąć wywołanie rbind z unikalnym: unique(do.call(rbind, list.of.tables))Zastąpienie unikatowej (rbind()) podczas korzystania z data.tables

To na pewno działa, ale jest dość powolne. W moim prawdziwym przypadku tabele mają dwie kolumny; łańcuch i rozmiar skrótu. W tym momencie kodu są one nie-kluczowane. Grałem najpierw z kluczowaniem przez mieszanie, ale zysk w połączeniu jest równoważony czasem kluczowania.

Oto jak odwzorować te opcje:

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) 

Grałem około z tableLength i czasy i nie widać dużą różnicę w wydajności. Czuję, że tam musi być więcej danych.table-ish sposób to zrobić.

W praktyce muszę to zrobić z wieloma tabelami danych, nie dwiema, więc skalowalność jest bardzo ważna; Chciałem tylko, aby powyższy kod był prosty.

Z góry dziękuję!

Odpowiedz

5

myślę chcesz użyć rbindlist i unique.data.table ...

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

+1 Btw, '' by' unique' zyski w v1.8.10 (na CRAN) na większą elastyczność (dzięki Steve) a 'list()' nie kopiuje już nazwanych wejść (jak w tym przykładzie) w GNU R v3.1.0 (o czym v1.8.10 wie i lubi). –

+0

Wow, zaskoczony, że to przegapiłem. Dostaję skromniejszy zysk, niż miałem nadzieję; czy nie ma lepszego sposobu? – ClaytonJY

+1

@ClaytonJY wyjmij 'rbinding' z funkcji i przetestuj * tylko * różnicę w' rbind' vs. 'rbindlist'. Myślę, że większość czasu spędzasz w innych miejscach w twoich funkcjach. –

Powiązane problemy