Виберіть рядки з кадру даних на основі значень у векторі


75

У мене є дані, подібні до цього:

dt <- structure(list(fct = structure(c(1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), X = c(2L, 4L, 3L, 2L, 5L, 4L, 7L, 2L, 9L, 1L, 4L, 2L, 5L, 4L, 2L)), .Names = c("fct", "X"), class = "data.frame", row.names = c(NA, -15L))

Я хочу вибрати рядки з цього кадру даних на основі значень у fctзмінній. Наприклад, якщо я хочу вибрати рядки, що містять або "a", або "c", я можу зробити це:

dt[dt$fct == 'a' | dt$fct == 'c', ]

який дає врожай

1    a 2
3    c 3
5    c 5
7    a 7
9    c 9
10   a 1
12   c 2
14   c 4

як і очікувалося. Але мої фактичні дані є більш складними, і я насправді хочу вибрати рядки на основі значень у векторі, таких як

vc <- c('a', 'c')

Тож я спробував

dt[dt$fct == vc, ]

але, звичайно, це не працює. Я знаю, що міг би щось кодувати, щоб прокрутити вектор і витягнути необхідні рядки та додати їх до нового кадру даних, але я сподівався, що є більш елегантний спосіб.

Отже, як я можу фільтрувати / підгрупувати свої дані на основі вмісту вектора vc?


13
try: dt[dt$fct %in% vc,] В основному ==це для одного елемента і %in%для векторного порівняння.
Тайлер Рінкер,

Відповіді:


133

Погляньте ?"%in%".

dt[dt$fct %in% vc,]
   fct X
1    a 2
3    c 3
5    c 5
7    a 7
9    c 9
10   a 1
12   c 2
14   c 4

Ви також можете використовувати ?is.element:

dt[is.element(dt$fct, vc),]


11

Іншим варіантом буде використання ключа data.table:

library(data.table)
setDT(dt, key = 'fct')[J(vc)]  # or: setDT(dt, key = 'fct')[.(vc)]

в результаті чого:

   fct X
1:   a 2
2:   a 7
3:   a 1
4:   c 3
5:   c 5
6:   c 9
7:   c 2
8:   c 4

Що це робить:

  • setDT(dt, key = 'fct')перетворює data.framea на data.table(що є вдосконаленою формою a data.frame) із fctстовпцем, встановленим як ключ.
  • Далі ви можете просто підмножину з vcвектором за допомогою [J(vc)].

ПРИМІТКА: коли ключ є змінною множник / символ, ви також можете використовувати, setDT(dt, key = 'fct')[vc]але це не буде працювати, коли vcє числовим вектором. Коли vcє числовим вектором і не загорнуто в J()або .(), vcбуде працювати як рядовий індекс.

Більш детальне пояснення концепції ключів та піднабору можна знайти в розділі "Віньєтка" та підмножина на основі швидкого двійкового пошуку .

Альтернатива, запропонована @Frank у коментарях:

setDT(dt)[J(vc), on=.(fct)]

Коли vcмістять значення, яких немає dt, потрібно додати nomatch = 0:

setDT(dt, key = 'fct')[J(vc), nomatch = 0]

або:

setDT(dt)[J(vc), on=.(fct), nomatch = 0]

Я не можу змусити це працювати, коли вектор і змінна в data.table є числовими. Будь-які ідеї?
Gaurav Singhal

@GauravSinghal оновив відповідь, метод у попередній версії працював над стовпцями символів / факторів; оновлений метод також працює для цілочисельних / числових стовпців
Яап,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.