Od V 1.9.4 data.table
jest zoptymalizowany do korzystania z pliku binarnego dołączyć na %in%
w przypadku, gdy zbiór danych jest już nadwozia. Więc @Richards odpowiedź powinna mieć taką samą osiągów dla najnowszych data.table
wersjach (btw, %in%
miały błąd, gdy używany podczas datatable.auto.index = TRUE
, więc upewnij się, że masz data.table
v 1.9.6+ zainstalowany, jeśli masz zamiar go używać)
Poniżej jest ilustracją data.table
użyciu binarny dołączyć podczas używania %in%
funkcję
require(data.table)
set.seed(123)
dt <- data.table (a = sample(letters, 25, replace = T),
b = sample(50:100, 25, replace = F))
dtv <- data.table(vowel = c('a','e','i','o','u'))
setkey(dt, a)
options(datatable.verbose = TRUE)
dt[a %in% dtv$vowel]
# Starting bmerge ...done in 0 secs <~~~ binary join was triggered
# a b
# 1: i 87
# 2: o 84
# 3: o 62
# 4: u 77
Tak czy inaczej, były prawie tam i można łatwo modyfikować c
podczas łączenia
dt[, c := 'consonant']
dt[dtv, c := 'vowel']
Lub jeśli chcesz uniknąć niepotrzebnego łączenia kolumn z dtv
(w przypadku gdy są obecne) można przyłączyć tylko do pierwszej kolumny w dtv
dt[dtv$vowel, c := 'consonant']
Zauważ, że nie wykorzystać .()
lub J()
. data.table
wykona domyślnie łączenie binarne zamiast indeksowania wierszy w przypadku, gdy element nie jest typu integer
lub numeric
. Ma to duże znaczenie, jeśli na przykład chcesz wykonać połączenie binarne nad kolumną b
(która jest typu integer
).Porównaj
setkey(dt, b)
dt[80:85]
# a b <~~~ binary join wan't triggered, instead an attempt to subset by rows 80:85 was made
# 1: NA NA
# 2: NA NA
# 3: NA NA
# 4: NA NA
# 5: NA NA
# 6: NA NA
I
dt[.(80:85)] # or dt[J(80:85)]
# Starting bmerge ...done in 0 secs <~~~ binary join was triggered
# a b
# 1: x 80
# 2: x 81
# 3: NA 82
# 4: NA 83
# 5: o 84
# 6: NA 85
Kolejną różnicą pomiędzy tymi dwoma metodami jest to, że nie powróci %in%
niedopasowane instancji, porównaj
setkey(dt, a)
dt[a %in% dtv$vowel]
# Starting bmerge ...done in 0 secs
# a b
# 1: i 87
# 2: o 84
# 3: o 62
# 4: u 77
I
dt[dtv$vowel]
# Starting bmerge ...done in 0 secs
# a b
# 1: a NA <~~~ unmatched values returned
# 2: e NA <~~~ unmatched values returned
# 3: i 87
# 4: o 84
# 5: o 62
# 6: u 77
W tym konkretnym przypadku nie ma znaczenia, ponieważ :=
nie będą modyfikować wartości niedopasowane, ale można użyć nomatch = 0L
w innych przypadkach
dt[dtv$vowel, nomatch = 0L]
# Starting bmerge ...done in 0 secs
# a b
# 1: i 87
# 2: o 84
# 3: o 62
# 4: u 77
Nie zapomnij ustawić options(datatable.verbose = FALSE)
jeśli nie nie chcę, żeby data.table
było tak gadatliwe.