filter(flights, month == 11 | month == 12)
运算顺序与英语表达不同。你不能写成 filter(flights, month == 11 | 12),如果按字面直译,它似乎表示“找出所有在十一月或十二月出发的航班”。但实际上它找出的是所有等于 11 | 12 的月份,这是一个结果为 TRUE 的表达式。在数值上下文中(比如这里),TRUE 会变成 1,所以这会找出所有一月份的航班,而不是十一月或十二月的航班。这非常容易让人困惑!
解决这个问题的实用简写是 x %in% y。它会选出 x 是 y 中某个值的所有行。我们可以用它重写前面的代码:
nov_dec <- filter(flights, month %in% c(11, 12))
有时,记住德摩根定律可以简化复杂的子集筛选:!(x & y) 等价于 !x | !y,而 !(x | y) 等价于 !x & !y。例如,如果你想找出到达或出发延误都不超过两小时的航班,可以使用以下两种筛选中的任意一种:
filter(flights, !(arr_delay > 120 | dep_delay > 120)) filter(flights, arr_delay <= 120, dep_delay <= 120)
除了 & 和 |,R 还有 && 和 ||。不要在这里使用它们!你将在第 276 页的“条件执行”一节中学习何时应该使用它们。
每当你在 fil ter() 中开始使用复杂的多部分表达式时,请考虑将它们改为显式变量。这样会更容易检查你的工作。你很快就会学到如何创建新变量。
缺失值
R 中有一个重要特性会让比较变得棘手,那就是缺失值,即 NA(“不可用”)。NA 表示一个未知的值,因此缺失值具有“传染性”;几乎所有涉及未知值的运算,其结果也是未知的:
NA > 5 #> [1] NA 10 == NA #> [1] NA NA + 10 #> [1] NA