data.table
Toetsen en indices gebruiken
Zoeken…
Invoering
Opmerkingen
De officiële vignetten zijn de beste inleiding tot dit onderwerp:
- "Sleutels en snelle binaire op zoek gebaseerde subset"
- "Secundaire indices en automatische indexering"
Sleutels versus indices
Een data.table kan worden "ingetoetst" door een reeks kolommen, die geïnteresseerde functies vertellen dat de gegevens op die kolommen zijn gesorteerd. Om of stel de sleutel, gebruik maken van de functies gedocumenteerd op ?key
.
Evenzo kunnen functies profiteren van de "indices" van een data.table. Elke index - en een tabel kan er meerdere hebben - slaat informatie op over de volgorde van de gegevens met betrekking tot een reeks kolommen. Net als een sleutel kan een index bepaalde taken versnellen. Gebruik de functies gedocumenteerd bij ?indices
om indices te krijgen of in te stellen.
Indices kunnen ook automatisch worden ingesteld (momenteel slechts voor één kolom tegelijk). Zie ?datatable.optimize
voor details over hoe dit werkt en hoe het indien nodig kan worden uitgeschakeld.
Verificatie en bijwerken
Ontbrekende waarden zijn toegestaan in een sleutelkolom.
Sleutels en indices worden opgeslagen als attributen en komen mogelijk per ongeluk niet overeen met de feitelijke volgorde van de gegevens in de tabel. Veel functies controleren de geldigheid van de sleutel of index voordat deze wordt gebruikt, maar het is de moeite waard om er rekening mee te houden.
Sleutels en indices worden na updates verwijderd, waarbij het niet duidelijk is dat de sorteervolgorde behouden blijft. Bijvoorbeeld, uitgaande van DT = data.table(a=c(1,2,4), key="a")
, als we updaten zoals DT[2, a := 3]
, is de sleutel verbroken.
Verbetering van de prestaties voor het selecteren van 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)
)
Overeenkomend op één kolom
Na de eerste run van een subsetbewerking met ==
of %in%
...
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0.12 0.03 0.16
Er is automatisch een index gemaakt voor g1
. Volgende subset-bewerkingen worden vrijwel onmiddellijk uitgevoerd:
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0 0 0
Als u wilt controleren wanneer een index wordt gemaakt of gebruikt, voegt u de optie verbose=TRUE
of wijzigt u de options(datatable.verbose=TRUE)
algemene instellingen options(datatable.verbose=TRUE)
.
Overeenkomen met meerdere kolommen
Op dit moment maakt het matchen op twee kolommen niet automatisch een index:
system.time(
DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
# user system elapsed
# 0.57 0.00 0.57
Voer dit opnieuw uit en het zal langzaam blijven. Zelfs als we de index handmatig toevoegen met setindex(DT, g1, g2)
, blijft deze traag omdat deze query nog niet door het pakket is geoptimaliseerd.
Gelukkig kunnen we, als we de waardencombinaties kunnen vinden waarnaar we willen zoeken en er een index beschikbaar is, snel aan elkaar deelnemen:
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
Met CJ
is het belangrijk om op te letten dat het aantal combinaties te groot wordt.