data.table
Verwenden von Schlüsseln und Indizes
Suche…
Einführung
Bemerkungen
Die offiziellen Vignetten sind die beste Einführung in dieses Thema:
Schlüssel vs. Indizes
Eine data.table kann durch eine Folge von Spalten "eingetippt" werden, um interessierten Funktionen mitzuteilen, dass die Daten nach diesen Spalten sortiert werden. Verwenden Sie zum Abrufen oder Einstellen der Taste die unter ?key
.
In ähnlicher Weise können Funktionen die "Indizes" von data.table nutzen. Jeder Index - und eine Tabelle kann mehr als einen haben - speichert Informationen über die Reihenfolge der Daten in Bezug auf eine Reihenfolge von Spalten. Wie ein Schlüssel kann ein Index bestimmte Aufgaben beschleunigen. Verwenden Sie zum Abrufen oder Setzen von Indizes die unter ?indices
dokumentierten Funktionen.
Indizes können auch automatisch gesetzt werden (derzeit nur für eine einzelne Spalte). Informationen dazu, wie dies funktioniert und wie es deaktiviert werden kann, finden Sie unter ?datatable.optimize
.
Überprüfung und Aktualisierung
Fehlende Werte sind in einer Schlüsselspalte zulässig.
Schlüssel und Indizes werden als Attribute gespeichert und entsprechen möglicherweise nicht der tatsächlichen Reihenfolge der Daten in der Tabelle. Viele Funktionen prüfen die Gültigkeit des Schlüssels oder des Indexes, bevor Sie ihn verwenden.
Schlüssel und Indizes werden nach Updates entfernt, wobei die Sortierreihenfolge nicht offensichtlich ist. Zum Beispiel, ausgehend von DT = data.table(a=c(1,2,4), key="a")
, wenn wir wie DT[2, a := 3]
aktualisieren, ist der Schlüssel gebrochen.
Verbesserung der Leistung bei der Auswahl von Subsets
# example data
set.seed(1)
n = 1e7
ng = 1e4
DT = data.table(
g1 = sample(ng, n, replace=TRUE),
g2 = sample(ng, n, replace=TRUE),
v = rnorm(n)
)
Übereinstimmung auf einer Spalte
Nach dem ersten Durchlauf eines Subsetting-Vorgangs mit ==
oder %in%
...
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0.12 0.03 0.16
Für g1
automatisch ein Index erstellt. Nachfolgende Subsetting-Vorgänge laufen fast sofort ab:
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0 0 0
Um zu überwachen, wann ein Index erstellt oder verwendet wird, fügen Sie die Option verbose=TRUE
oder ändern Sie die globalen Einstellungsoptionen options(datatable.verbose=TRUE)
.
Übereinstimmung auf mehreren Spalten
Gegenwärtig wird beim Zuordnen in zwei Spalten kein Index automatisch erstellt:
system.time(
DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
# user system elapsed
# 0.57 0.00 0.57
Führen Sie dies erneut aus und es bleibt langsam. Selbst wenn wir den Index manuell mit setindex(DT, g1, g2)
hinzufügen, bleibt er langsam, da diese Abfrage vom Paket noch nicht optimiert wurde.
Glücklicherweise können wir, wenn wir die Kombinationen von Werten auflisten können, nach denen gesucht werden soll und ein Index verfügbar ist, schnell einen Equi-Join herstellen:
system.time(
DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
# user system elapsed
# 0.53 0.00 0.54
setindex(DT, g1, g2)
system.time(
DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
# user system elapsed
# 0 0 0
Bei CJ
ist es wichtig, darauf zu achten, dass die Anzahl der Kombinationen zu groß wird.