Следующий код находит все рейсы, которые вылетели в феврале или марте:
filter(flights, month == 2 | month == 3)
Если попытаться ввести команду буквально
filter(flights, month == (2|3))
то вместо желаемого будут найдены все месяцы равные результату булевой операции 2|3, значение которой обращается в TRUE. В числовом контексте TRUE становится равным единице 1, поэтому будут найдены все январские вылеты, что вовсе не соответствует задуманному.
Полезным клавиатурным сокращением для решения обозначенной проблемы является x %in% y. Это позволит выбрать каждую строку, где x является одним из значений в y. Можно было бы использовать следующую альтернативу для кода выше:
filter(flights, month %in% c(2, 3))
Иногда можно упростить сложное выражение вспомнив законы де Моргана из курса математической логики: !(x & y) == !х | !y, и !(x | y) == !x & !y. Например, если нужно найти рейсы, которые не задерживались (по прилету или отправлению) более чем на час, можно воспользоваться любым из следующих фильтров:
filter(flights,!(arr_delay > 60 | dep_delay > 60))
filter(flights, arr_delay <= 60, dep_delay <= 60)
Кроме & и |, в R есть && и ||, но не используйте их сейчас, позже узнаете, при каких условиях уместно их применение.
Всякий раз, когда используется сложное составное выражение в filter(), предпочтительнее разбить выражение на несколько вспомогательных, это значительно упрощает последующую проверку работы. Вскоре узнаем, как быстро создать новые переменные. Одна важная особенность R, которая может затруднить фильтрацию, это пропущенные значения, или недоступные (NA), которые представляют собой неизвестное значение, поэтому пропущенные значения являются изгоями, практически любая операция с участием NA приведет к NA.
NA > 1
#> [1] NA
2 == NA
#> [1] NA
NA + 3
#> [1] NA
NA / 4
#> [1] NA
Самым алогичным результатом может показаться следующий:
NA == NA
#> [1] NA
Но его легко понять в конкретном контексте: совпадает ли содержимое двух ящиков, внутри которых неизвестно что? Мы не знаем! Если хотите определить, отсутствует ли значение конкретной переменной, можно воспользоваться функцией is.na(), в качестве аргумента задав интересующее имя. Функция filter() отбирает только те строки, для проверяемые условия обращаются в TRUE, при этом исключаются как значения FALSE, так и NA. Если хотите сохранить пропущенные значения, то запрашивайте их в явном виде:
filter (flights, is.na(month) | month > 1)
Упражнения
1. Найти все рейсы, которые: имели задержку прибытия на два и более часа; прилетели в Хьюстон; управлялись компанией Delta; улетели летом; прибыл с опозданием более чем на два часа; задержались они как минимум на час, но наверстали более 30 минут в полете; отбыли между полуночью и 6 утра (включительно).
2. Функция between() из пакета dplyr тоже полезна