2015-12-07 13 views
6

Nie wiem, jak uzyskać indeksy wierszy wynikające z łączenia dwóch tabel danych.Czy mogę użyć funkcji łączenia danych R data.table w celu wybrania wierszy i wykonania niektórych operacji?

Aby ustawić uproszczony przykład, załóżmy, że dt to data.table z kolumną "a", która jest literą alfabetu, "b" to jakaś inna informacja.

Chcę dodać kolumnę "c" i ustawić ją na "samogłoskę" lub "spółgłoskę" w zależności od kolumny "a". Mam kolejną tabelę danych dtv, która służy jako tabela samogłosek. Czy mogę użyć możliwości łączenia w pliku data.table, aby wydajnie wykonać tę operację?

require(data.table) 
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) 

Następny wiersz kodu daje mi data.table wierszy z samogłosek

dt[dtv, nomatch=0] 

Ale jak mogę chwycić indeksy wierszy więc można oznaczać z kłótnią samogłosek lub spółgłosek jak?

dt[, c := 'consonant'] 
dt[{ `a` found in vowel list }, c := 'vowel'] 
# I want to do this where column 'a' is a vowel 

Odpowiedz

4

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.

3

Naprawdę nie ma potrzeby korzystania z łączenia/łączenia. Możemy użyć %in%.

dt[, c := "consonant"] 
dt[a %in% dtv$vowel, c := "vowel"] 

lub samo w jednej linii -

dt[, c := "consonant"][a %in% dtv$vowel, c := "vowel"] 

Alternatywnie (i lepiej), możemy zrobić zarówno z tych etapów w jednej rozmowy z następujących czynności.

dt[, c := c("consonant", "vowel")[a %in% dtv$vowel + 1L]]