data.table
Verbindet und verschmilzt
Suche…
Einführung
?`[.data.table`
für die offiziellen Dokumente ein.
Syntax
- x [i, on, j]
# join: data.table x & data.table oder Liste i - x [! i, on, j]
# Anti-Join
Bemerkungen
Arbeiten mit Schlüsseltabellen
Wenn x
und i
einen Schlüssel haben oder x
ersten Spalten von i
übereinstimmt, kann das on
wie x[i]
übersprungen werden.
Gemeinsame Definition von Spaltennamen
In j
von x[i, on, j]
können Spalten von i
mit den Präfixen i.*
Referenziert werden.
Gruppierung in Subsets
In j
von x[i, on, j, by=.EACHI]
wird j
für jede Zeile von i
berechnet.
Dies ist der einzige Wert by
Wert verwenden. Für andere Werte stehen keine Spalten von i
zur Verfügung.
Werte in einem Join aktualisieren
Wenn Daten "aufgeräumt" sind, werden sie häufig in mehreren Tabellen organisiert. Um die Daten für die Analyse zu kombinieren, müssen wir eine Tabelle mit Werten aus einer anderen "aktualisieren".
Zum Beispiel könnten Umsatzdaten für Leistungen vorliegen, in denen Attribute des Ausführenden (seines Budgets) und des Ortes (seiner Population) in separaten Tabellen gespeichert werden:
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
Wenn wir zu einer Analyse bereit sind, müssen wir Variablen aus diesen anderen Tabellen entnehmen:
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
Es wird eine copy
, um eine Verunreinigung der Rohdaten zu vermeiden, aber wir könnten stattdessen direkt an mainDT
.
Vorteile bei der Verwendung separater Tabellen
Die Vorteile dieser Struktur werden in dem Papier über ordentliche Daten behandelt, jedoch in diesem Zusammenhang:
Verfolgung von fehlenden Daten Nur Zeilen, die in der Zusammenführung übereinstimmen, erhalten eine Zuweisung. Wir haben keine Daten für
geo_id == "MO"
oben, daher sind seine Variablen in unserer letzten TabelleNA
. Wenn wirgeoDT
fehlenden Daten unerwartet sehen, können wir sie auf die fehlende Beobachtung in dergeoDT
TabellegeoDT
und von dort aus untersuchen, ob wir ein Datenproblem haben, das angegangen werden kann.Verständlichkeit. Beim Aufbau unseres statistischen Modells ist es möglicherweise wichtig zu bedenken, dass das
budget
für jeden Künstler konstant ist. Im Allgemeinen zahlt sich das Verständnis der Struktur der Daten aus.Speichergröße. Es kann eine große Anzahl von Darsteller- und Standortattributen geben, die nicht im statistischen Modell enden. Auf diese Weise müssen wir sie nicht in die (möglicherweise massive) Tabelle aufnehmen, die für die Analyse verwendet wird.
Spalten programmgesteuert bestimmen
Wenn pDT
viele Spalten pDT
, wir jedoch nur einige auswählen möchten, können wir diese verwenden
p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]
Die Klammern um (p_cols) :=
sind wesentlich, wie im Dokument zum Erstellen von Spalten angegeben .
Equi-Join
# 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
Intuition
Denken Sie an x[i]
als Auswahl einer Teilmenge von x
für jede Zeile von i
. Diese Syntax spiegelt das Matrix-Subsetting in der Basis R wider und stimmt mit dem ersten Argument überein, das "wo" bedeutet, in DT[where, select|update|do, by]
.
Man könnte sich fragen, warum diese neue Syntax lernenswert ist, da merge(x,i)
noch mit data.tables funktioniert. Die kurze Antwort ist, dass wir normalerweise etwas zusammenführen und dann etwas weiter machen wollen. Die x[i]
-Syntax erfasst dieses Verwendungsmuster und ermöglicht eine effizientere Berechnung. Weitere Informationen finden Sie in den FAQs 1.12 und 2.14 .
Umgang mit mehrfach übereinstimmenden Zeilen
Standardmäßig wird jede Zeile a
übereinstimmenden Zeile von b
zurückgegeben:
a[b, on="id"]
# id x y
# 1: 1 11 -1
# 2: 1 12 -1
# 3: 2 13 -2
Dies kann mit mult
:
a[b, on="id", mult="first"]
# id x y
# 1: 1 11 -1
# 2: 2 13 -2
Umgang mit nicht übereinstimmenden Zeilen
Standardmäßig werden nicht übereinstimmende Zeilen a
Standbilds im Ergebnis angezeigt:
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
Um diese auszublenden, benutze nomatch
:
b[a, on="id", nomatch=0]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
Beachten Sie, dass x[i]
versuchen wird, NAs in i
abzugleichen.
Zählende Übereinstimmungen wurden zurückgegeben
Um die Anzahl der Übereinstimmungen für jede Zeile von i
, verwenden Sie .N
und 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