data.table
Używanie kluczy i indeksów
Szukaj…
Wprowadzenie
Uwagi
Oficjalne winiety to najlepsze wprowadzenie do tego tematu:
Klucze a wskaźniki
Tabela danych może być „kluczowana” sekwencją kolumn, informując zainteresowane funkcje, że dane są sortowane według tych kolumn. Aby uzyskać lub ustawić klucz, użyj funkcji udokumentowanych w ?key
Podobnie funkcje mogą korzystać z „indeksów” data.table. Każdy indeks - i tabela może mieć więcej niż jeden - przechowuje informacje o kolejności danych w odniesieniu do sekwencji kolumn. Indeks, podobnie jak klucz, może przyspieszyć niektóre zadania. Aby uzyskać lub ustawić indeksy, użyj funkcji udokumentowanych w ?indices
Indeksy można również ustawiać automatycznie (obecnie tylko dla jednej kolumny na raz). Zobacz ?datatable.optimize
aby uzyskać szczegółowe informacje na temat tego, jak to działa i jak je wyłączyć, jeśli to konieczne.
Weryfikacja i aktualizacja
Brakujące wartości są dozwolone w kluczowej kolumnie.
Klucze i indeksy są przechowywane jako atrybuty i mogą przypadkowo nie odpowiadać rzeczywistej kolejności danych w tabeli. Wiele funkcji sprawdza poprawność klucza lub indeksu przed jego użyciem, ale warto o tym pamiętać.
Klucze i indeksy są usuwane po aktualizacjach, gdzie nie jest oczywiste, że kolejność sortowania jest zachowana. Na przykład, zaczynając od DT = data.table(a=c(1,2,4), key="a")
, jeśli aktualizujemy jak DT[2, a := 3]
, klucz jest uszkodzony.
Poprawa wydajności wybierania podzbiorów
# 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)
)
Dopasowywanie w jednej kolumnie
Po pierwszym uruchomieniu operacji podzbioru z ==
lub %in%
...
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0.12 0.03 0.16
Indeks został utworzony automatycznie dla g1
. Kolejne operacje podzestawów uruchamiane są niemal natychmiast:
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0 0 0
Aby monitorować, kiedy indeks jest tworzony lub używany, dodaj opcję verbose=TRUE
lub zmień options(datatable.verbose=TRUE)
ustawień globalnych options(datatable.verbose=TRUE)
.
Dopasowywanie w wielu kolumnach
Obecnie dopasowanie dwóch kolumn nie powoduje automatycznego utworzenia indeksu:
system.time(
DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
# user system elapsed
# 0.57 0.00 0.57
Uruchom to ponownie, a pozostanie wolne. Nawet jeśli ręcznie dodamy indeks za pomocą setindex(DT, g1, g2)
, pozostanie on wolny, ponieważ to zapytanie nie zostało jeszcze zoptymalizowane przez pakiet.
Na szczęście, jeśli potrafimy wyliczyć kombinacje wartości, które chcemy wyszukać, a indeks jest dostępny, możemy szybko połączyć equi:
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
W przypadku CJ
ważne jest, aby uważać na zbyt dużą liczbę kombinacji.