Фильтровать несколько значений по столбцу строки в dplyr

у меня есть data.frame с символьными данными в одном из столбцов. Я хотел бы отфильтровать несколько параметров в data.frame из той же колонке. Есть ли простой способ сделать это, которого мне не хватает?

пример: data.frame name = dat

days      name
88        Lynn
11          Tom
2           Chris
5           Lisa
22        Kyla
1          Tom
222      Lynn
2         Lynn

Я хотел бы отфильтровать Tom и Lynn например.
Когда я это делаю:

target <- c("Tom", "Lynn")
filt <- filter(dat, name == target)

Я получаю эту ошибку:

longer object length is not a multiple of shorter object length

3 ответов


вам нужно %in% вместо ==:

library(dplyr)
target <- c("Tom", "Lynn")
filter(dat, name %in% target)  # equivalently, dat %>% filter(name %in% target)

производит

  days name
1   88 Lynn
2   11  Tom
3    1  Tom
4  222 Lynn
5    2 Lynn

чтобы понять почему, рассмотрим, что происходит здесь:

dat$name == target
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

в основном, мы перерабатываем две длины target вектор четыре раза, чтобы соответствовать длине dat$name. Другими словами, мы делаем:

 Lynn == Tom
  Tom == Lynn
Chris == Tom
 Lisa == Lynn
 ... continue repeating Tom and Lynn until end of data frame

в этом случае мы не получаем ошибку, потому что я подозреваю, что ваш фрейм данных на самом деле имеет другое количество строк, которые не позволяют рециркулировать, но образец вы обеспечиваете ли (8 строк). Если бы в образце было нечетное количество строк, я бы получил ту же ошибку, что и вы. Но даже когда переработка работает, это явно не то, что вы хотите. В принципе, утверждение dat$name == target эквивалентно высказыванию:

возвращение TRUE для каждого нечетного значения, равного " Tom "или каждого четного значения, равного"Lynn".

так случилось, что последнее значение в вашем фрейме данных образца четное и равно "Линн", следовательно, один TRUE выше.

в противоположность dat$name %in% target говорит:

для каждого значения dat$name, проверьте, что он существует в target.

очень разные. Вот результат:

[1]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE

обратите внимание, ваша проблема не имеет ничего общего с dplyr, просто неправильное использование ==.


С помощью :

df <- data.frame(days = c(88, 11, 2, 5, 22, 1, 222, 2), name = c("Lynn", "Tom", "Chris", "Lisa", "Kyla", "Tom", "Lynn", "Lynn"))

# Three lines
target <- c("Tom", "Lynn")
index <- df$name %in% target
df[index, ]

# One line
df[df$name %in% c("Tom", "Lynn"), ] 

выход:

  days name
1   88 Lynn
2   11  Tom
6    1  Tom
7  222 Lynn
8    2 Lynn

используя sqldf:

library(sqldf)
# Two alternatives:
sqldf('SELECT *
      FROM df 
      WHERE name = "Tom" OR name = "Lynn"')
sqldf('SELECT *
      FROM df 
      WHERE name IN ("Tom", "Lynn")')

этого можно достигнуть используя пакет dplyr, который имеющийся в CRAN. Простой способ добиться этого:

  1. установить .

  2. library(dplyr) df<- select(filter(dat,name=='tom'| name=='Lynn',c('days','name))

объяснение:

Итак, как только мы загрузили dplyr, мы создаем новый фрейм данных, используя две разные функции из этого пакета:

фильтр: первый аргумент-это фрейм данных; второй аргумент-условие, по которому мы хотим, чтобы он был разделен. В результате получается весь фрейм данных только с теми строками, которые мы хотели. select: первый аргумент-фрейм данных; второй аргумент-имена столбцов, которые мы хотим выбрать из него. Нам не нужно использовать функцию names (), и нам даже не нужно использовать кавычки. Мы просто перечисляем имена столбцов как объекты.