Szukaj…


Wprowadzenie

Łączenie łączy dwie tabele zawierające powiązane kolumny. Termin obejmuje szeroki zakres operacji, w zasadzie wszystko oprócz dołączenia dwóch tabel . „Scalanie” jest synonimem. Wpisz ?`[.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:

  1. Ś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 tabeli geoDT i zbadać stamtąd, czy mamy problem z danymi, który można rozwiązać.

  2. 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.

  3. 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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow