Это на самом деле не проблема dplyr
.
Как уже упоминалось, a == b
проверяет, идентична ли каждая пара элементов, то есть a[1] == b[1]
, a[2] == b[2]
и т. Д.(Взгляните на ?Comparison
.) Вы сравниваете векторы неодинаковой длины и с длинами, которые не пригодны для повторного использования одного из них, чтобы соответствовать другому, что и является причиной того, что вы получили предупреждение.
Вместо этого a %in% b
проверяет, существует ли каждый элемент в a
где-нибудь в b
, и возвращает true или false для каждого элемента в a
.
Для иллюстрации с вашими данными:
library(dplyr)
a <- 1:20
b <- rep(c("Blue", "Green", "White", "Grey"),5)
df <- data.frame(Numbers=a, colours=b)
В представлении a %in% b
это ваша b
:
levels(df$colours)[1:3]
#> [1] "Blue" "Green" "Grey"
Проверка наличия каждого элемента colours
в этом наборе значений дает логическоеvector:
df$colours %in% levels(df$colours)[1:3]
#> [1] TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE
#> [12] TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE
Базовая версия R dplyr::filter
выглядит следующим образом, принимая элементы df$colours
, для которых предыдущая операция дает TRUE
:
df$colours[df$colours %in% levels(df$colours)[1:3]]
#> [1] Blue Green Grey Blue Green Grey Blue Green Grey Blue Green
#> [12] Grey Blue Green Grey
#> Levels: Blue Green Grey White
Indplyr
, нестандартная оценка отбрасывает необходимость в df$
, но вы делаете по существу то же самое в dplyr::filter
: обнаружение, находится ли каждый элемент colours
в подмножестве значений levels(colours)[1:3]
, а затемфильтрация только для тех строк, которые соответствуют TRUE
.
df %>%
filter(colours %in% levels(colours)[1:3])
#> Numbers colours
#> 1 1 Blue
#> 2 2 Green
#> 3 4 Grey
#> 4 5 Blue
#> 5 6 Green
#> 6 8 Grey
#> 7 9 Blue
#> 8 10 Green
#> 9 12 Grey
#> 10 13 Blue
#> 11 14 Green
#> 12 16 Grey
#> 13 17 Blue
#> 14 18 Green
#> 15 20 Grey