2015-04-28 6 views
6

Podczas dołączania do tabeli danych X i Y za pomocą X [Y], X musi mieć klucz, którego klucz Y używa do połączenia. Jeśli X jest bardzo dużą tabelą i zwykle wpisuje się w kolumny, które nie są używane w łączeniu, to klucz X musi zostać zmieniony dla łączenia, a następnie przywrócony z powrotem do oryginalnego klucza po złączeniu. Czy istnieje skuteczny sposób łączenia, bez utraty pierwotnego klucza głównego na X?Jak wykonać sprzężenie danych X [Y] data.table, bez utraty istniejącego klucza głównego na X?

Mam duży zbiór danych DT środowiska środowiska czasowego (1M wierszy, 36 kolumn), jako data.table z kluczem w witrynie i kolumny daty. Muszę wykonać obliczenia na istniejących kolumnach w DT i/lub wstawić nową kolumnę, opartą na istniejącej kolumnie, używając małej tabeli odnośników lub przekodowań.

Oto minimalne przykład:

require(data.table) # using v1.9.5 

# main data table DT, keyed on site and date, with data column x 
DT <- data.table(site = rep(LETTERS[1:2], each=3), 
       date = rep(1:3, times=2), 
       x = rep(1:3*10, times=2), 
       key = "site,date") 
DT 
# site date x 
# 1: A 1 10 
# 2: A 2 20 
# 3: A 3 30 
# 4: B 1 10 
# 5: B 2 20 
# 6: B 3 30 

# lookup table for x to y lookup, keyed on x 
x2y <- data.table(x = c(10,20), y = c(100,200), key = "x") 
x2y 
#  x y 
# 1: 10 100 
# 2: 20 200 

Aby dołączyć do X2Y tabeli przeglądowej z głównej tabeli DT, ustawić klucz DT do "x":

setkey(DT,x) 

Następnie dołączyć prace zgodnie z oczekiwaniami.

DT[x2y] 
# site date x y 
# 1: A 1 10 100 
# 2: B 1 10 100 
# 3: A 2 20 200 
# 4: B 2 20 200 

i mogę użyć "y" z tabeli odnośników w obliczeniach lub utworzyć nową kolumnę w DT.

DT[x2y, y:=y] 
# site date x y 
# 1: A 1 10 100 
# 2: B 1 10 100 
# 3: A 2 20 200 
# 4: B 2 20 200 
# 5: A 3 30 NA 
# 6: B 3 30 NA 

Ale teraz mój czas serii DT zestaw danych jest osadzone na „x”, i muszę ustawić kluczyk z powrotem na „miejscu, data” do dalszego wykorzystania.

setkey(DT,site,date) 

Czy to podejście (X klawisz X, dołączyć, a następnie ponownie klucz) najszybszym sposobem, aby to zrobić, gdy DT jest bardzo duża (1M wierszy), czy jest tam równie skuteczny sposób na tego typu lookup join, bez utraty oryginalnego klucza na dużym stole DT?

+4

Niepowiązani ale 1mm wiersze to bardzo mały zestaw danych, którego wpisanie powinno zająć mniej niż sekundę. Właśnie testowałem 7MM i było to mniej niż sekundę. –

+1

@DavidArenburg Tak, kluczowanie jest szybkie, ale może znaczące, jeśli jest wykonywane wiele razy. Powodem pytania, którego nie wspomniałem, jest to, że piszę niektóre ogólne funkcje do wykonywania obliczeń na dużych zestawach danych za pomocą sprzężeń, i byłoby lepiej, gdyby funkcje nie zmieniły kluczy lub kolejność danych. jako argumenty, chyba że oczywiście zmieniono kolumny kluczowe. –

+1

Tak, rozumiem. Wspomniałem o tym, że nie ma to związku. Chociaż mały ptak wyszeptał mi, że twoja prośba jest na liście projektów deweloperów 'data.table'. –

Odpowiedz

4

Z kluczy wtórnych zrealizowanych (od v1.9.6) i niedawnym bug fix na utrzymanie/odrzucając klucze poprawnie (w v1.9.7), teraz możesz to zrobić używając on=:

# join 
DT[x2y, on="x"] # key is removed as row order gets changed. 

# update using joins 
DT[x2y, y:=y, on="x"] # key is retained, as row order isn't changed. 
7

Aktualizacja: Dzięki usunięciu błędu nie jest to już konieczne. Zobacz zaakceptowaną odpowiedź.


chciałbym przyłączyć tylko x:

DT[,y:=x2y[J(DT$x)]$y] 

Klucz DT jest zachowana tutaj.

+2

Dzięki, to działa dla mnie.Czekam na prostszą i bardziej intuicyjną składnię, gdy zostaną zaimplementowane sprzężenia na kluczach pomocniczych, o czym wspomniał Arun. . –

+2

Właśnie sprawdziłem czas na tę odpowiedź vs. mój OP, dla losowo zamówionego zestawu danych DT 2 x 1e6. Metoda OP (setkey, join, setkey) trwa 522 ms, a ta odpowiedź zajmuje 251 ms. Jest więc dwa razy szybszy niż moje podejście do PO. Próbowałem również dodać set2key (DT, x) do tej metody odpowiedzi, i zajęło to 426 ms, co oznacza, że ​​set2key nie pomogło, w obecnej data.table 1.9.5. –

Powiązane problemy