data.table
Łączy się i łączy
Szukaj…
Wprowadzenie
?`[.data.table`
dla oficjalnych dokumentów.
Składnia
- x [i, on, j]
# join: data.table x & data.table lub lista i - x [! ja, on, j]
# anti-join
Uwagi
Praca z tabelami z kluczami
Jeśli x
& i
mają klucz lub x
jest osadzone dopasować i
„s pierwsze kilka kolumn, a następnie on
można pominąć jak x[i]
.
Wspólne ujednoznacznianie nazw kolumn
W j
z x[i, on, j]
, kolumny i
można odnosić do prefiksów i.*
.
Grupowanie według podzbiorów
W j
o x[i, on, j, by=.EACHI]
, j
jest obliczana dla każdego rzędu i
.
Jest to jedyna wartość by
wartość używana. W przypadku innych wartości kolumny i
nie są dostępne.
Zaktualizuj wartości w złączeniu
Gdy dane są „uporządkowane” , często są podzielone na kilka tabel. Aby połączyć dane do analizy, musimy „zaktualizować” jedną tabelę o wartości z innej.
Na przykład możemy mieć dane dotyczące sprzedaży dotyczące występów, w których atrybuty wykonawcy (jego budżetu) i lokalizacji (jego populacji) są przechowywane w osobnych tabelach:
set.seed(1)
mainDT = data.table(
p_id = rep(LETTERS[1:2], c(2,4)),
geo_id = sample(rep(state.abb[c(1,25,50)], 3:1)),
sales = sample(100, 6)
)
pDT = data.table(id = LETTERS[1:2], budget = c(60, 75))
geoDT = data.table(id = state.abb[c(1,50)], pop = c(100, 200))
mainDT # sales data
# p_id geo_id sales
# 1: A AL 95
# 2: A WY 66
# 3: B AL 62
# 4: B MO 6
# 5: B AL 20
# 6: B MO 17
pDT # performer attributes
# id budget
# 1: A 60
# 2: B 75
geoDT # location attributes
# id pop
# 1: AL 100
# 2: WY 200
Kiedy jesteśmy gotowi przeprowadzić analizę, musimy pobrać zmienne z tych innych tabel:
DT = copy(mainDT)
DT[pDT, on=.(p_id = id), budget := i.budget]
DT[geoDT, on=.(geo_id = id), pop := i.pop]
# p_id geo_id sales budget pop
# 1: A AL 95 60 100
# 2: A WY 66 60 200
# 3: B AL 62 75 100
# 4: B MO 6 75 NA
# 5: B AL 20 75 100
# 6: B MO 17 75 NA
copy
jest pobierana, aby uniknąć zanieczyszczenia surowych danych, ale zamiast tego moglibyśmy pracować bezpośrednio na mainDT
.
Zalety korzystania z oddzielnych tabel
Zalety tej struktury zostały omówione w artykule na temat uporządkowanych danych, ale w tym kontekście:
Śledzenie brakujących danych. Tylko wiersze pasujące do scalenia otrzymują przypisanie. Nie mamy danych dla
geo_id == "MO"
powyżej, więc jego zmienne sąNA
w naszej końcowej tabeli. Jeśli nieoczekiwanie zobaczymy brakujące dane, możemy prześledzić je z powrotem do brakującej obserwacji w tabeligeoDT
i zbadać stamtąd, czy mamy problem z danymi, który można rozwiązać.Zrozumiałość. Budując nasz model statystyczny, może być ważne, aby pamiętać, że
budget
jest stały dla każdego wykonawcy. Zasadniczo zrozumienie struktury danych przynosi korzyści.Rozmiar pamięci. Może istnieć duża liczba atrybutów performera i lokalizacji, które nie kończą się w modelu statystycznym. W ten sposób nie musimy umieszczać ich w (prawdopodobnie masywnej) tabeli używanej do analizy.
Programowo określające kolumny
Jeśli w pDT
jest wiele kolumn, ale chcemy wybrać tylko kilka, możemy użyć
p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]
(p_cols) :=
wokół (p_cols) :=
są niezbędne, jak zauważono w dokumencie na temat tworzenia kolumn .
Równolegle
# example data
a = data.table(id = c(1L, 1L, 2L, 3L, NA_integer_), x = 11:15)
# id x
# 1: 1 11
# 2: 1 12
# 3: 2 13
# 4: 3 14
# 5: NA 15
b = data.table(id = 1:2, y = -(1:2))
# id y
# 1: 1 -1
# 2: 2 -2
Intuicja
Pomyśl o x[i]
jako wyborze podzbioru x
dla każdego wiersza i
. Ta składnia odzwierciedla podzbiór macierzy w bazie R i jest spójna z pierwszym argumentem oznaczającym „gdzie” w DT[where, select|update|do, by]
.
Można się zastanawiać, dlaczego warto nauczyć się tej nowej składni, ponieważ merge(x,i)
nadal działa z danymi.tabele. Krótka odpowiedź jest taka, że zazwyczaj chcemy się połączyć, a następnie zrobić coś dalej. Składnia x[i]
zwięźle wychwytuje ten wzorzec użycia, a także pozwala na bardziej wydajne obliczenia. Aby uzyskać bardziej szczegółowe wyjaśnienie, przeczytaj często zadawane pytania 1.12 i 2.14 .
Obsługa wielokrotnie dopasowanych wierszy
Domyślnie każdy wiersz a
dopasowanym każdym rzędzie b
są zwracane:
a[b, on="id"]
# id x y
# 1: 1 11 -1
# 2: 1 12 -1
# 3: 2 13 -2
Można to poprawić za pomocą mult
:
a[b, on="id", mult="first"]
# id x y
# 1: 1 11 -1
# 2: 2 13 -2
Obsługa niedopasowanych wierszy
Domyślnie niedopasowane wiersze nadal pojawiają się w wyniku: a
b[a, on="id"]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
# 4: 3 NA 14
# 5: NA NA 15
Aby je ukryć, użyj nomatch
:
b[a, on="id", nomatch=0]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
Zauważ, że x[i]
spróbuje dopasować NA w i
.
Liczenie meczów zwrócone
Aby policzyć liczbę dopasowań dla każdego wiersza i
, użyj .N
i by=.EACHI
.
b[a, on="id", .N, by=.EACHI]
# id N
# 1: 1 1
# 2: 1 1
# 3: 2 1
# 4: 3 0
# 5: NA 0