Фильтровать несколько условий 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
Ответы
Ответ 1
Вам нужно %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
эквивалентно высказыванию:
return TRUE
для каждого нечетного значения, равного "Tom" или любого четного значения, равного "Lynn".
Так получилось, что последнее значение в вашем кадре данных образца равно и равно "Lynn", следовательно, один TRUE
выше.
Чтобы контрастировать, dat$name %in% target
говорит:
для каждого значения в dat$name
, убедитесь, что он существует в target
.
Совсем другое. Вот результат:
[1] TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE
Обратите внимание, что ваша проблема не имеет ничего общего с dplyr
, просто неправильное использование ==
.
Ответ 2
Использование пакета base
:
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")')
Ответ 3
Это может быть достигнуто с помощью пакета dplyr, который доступен в CRAN. Простой способ добиться этого:
Пояснение:
Итак, как только мы загрузили dplyr, мы создаем новый фрейм данных, используя две различные функции из этого пакета:
filter: первым аргументом является кадр данных; второй аргумент - это условие, по которому мы хотим, чтобы оно было подмножеством. Результатом является весь фрейм данных только с теми строками, которые мы хотели.
select: первый аргумент - это кадр данных; второй аргумент - это имена столбцов, которые мы хотим выбрать из него. Нам не нужно использовать функцию names(), и нам даже не нужно использовать кавычки. Мы просто указываем имена столбцов как объекты.