Подтвердить что ты не робот

Выбор строк из фрейма данных на основе значений в векторе

У меня есть данные, подобные этому:

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?

4b9b3361

Ответ 1

Посмотрите ?"%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),]

Ответ 2

Как и выше, используя filter из dplyr:

filter(df, fct %in% vc)

Ответ 3

Другой вариант - использовать ключ 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.frame в data.table (который является расширенной формой data.frame) с столбцом fct, установленным как ключ.
  • Далее вы можете просто подмножить вектор vc с [J(vc)].

ПРИМЕЧАНИЕ. Когда ключ является переменной factor/character, вы также можете использовать setDT(dt, key = 'fct')[vc], но это не будет работать, если vc - числовой вектор. Когда vc является числовым вектором и не заключен в J() или .(), vc будет работать как index.exe.

Более подробное объяснение концепции ключей и подмножества можно найти в виньете "Ключи" и "Быстрое подмножество на основе бинарного поиска" .

Альтернатива, предложенная @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]