首页 > 解决方案 > 为什么括号会破坏我的 dplyr::filter() 输出?

问题描述

filter()当我遇到一个奇怪的结果时,我正在研究 R4DS 并了解该功能。我试图只找到 a 和 a 不到 2 分钟的filter观察结果。这是我的代表:tibbledep_delayarr_delay

library(tidyverse)
library(nycflights13)
filter(flights, dep_delay & arr_delay < 2)

正确输出

# A tibble: 187,645 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl>
 1  2013     1     1      544            545        -1     1004           1022       -18
 2  2013     1     1      554            600        -6      812            837       -25
 3  2013     1     1      557            600        -3      709            723       -14
 4  2013     1     1      557            600        -3      838            846        -8
 5  2013     1     1      558            600        -2      849            851        -2
 6  2013     1     1      558            600        -2      853            856        -3
 7  2013     1     1      558            600        -2      923            937       -14
 8  2013     1     1      559            600        -1      854            902        -8
 9  2013     1     1      601            600         1      844            850        -6
10  2013     1     1      602            610        -8      812            820        -8
# ... with 187,635 more rows, and 10 more variables: carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

但是,如果我出于某种原因添加括号,则输出会更改

filter(flights, (dep_delay & arr_delay) < 2)
# A tibble: 327,394 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl>
 1  2013     1     1      517            515         2      830            819        11
 2  2013     1     1      533            529         4      850            830        20
 3  2013     1     1      542            540         2      923            850        33
 4  2013     1     1      544            545        -1     1004           1022       -18
 5  2013     1     1      554            600        -6      812            837       -25
 6  2013     1     1      554            558        -4      740            728        12
 7  2013     1     1      555            600        -5      913            854        19
 8  2013     1     1      557            600        -3      709            723       -14
 9  2013     1     1      557            600        -3      838            846        -8
10  2013     1     1      558            600        -2      753            745         8
# ... with 327,384 more rows, and 10 more variables: carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

注意第 2 行的两个变量的值都不正确。起初我想也许通过添加我正在转换的括号(dep_delay & arr_delay)TRUE或者1但实际上会创建一个完全不同的输出。谁能帮我理解发生了什么?

标签: rfilterdplyr

解决方案


你没有得到你认为你得到的东西。

dep_delay & arr_delay < 2是两个独立的逻辑条件。

  1. dep_delay,这是有效的(dep_delay != 0)
  2. arr_delay > 2,这是不言而喻的。

事实上,只有 167,639 行在flightswheredep_delayarr_delaynon-NA小于 2。

with(flights, table(arr_delay < 2, dep_delay < 2, useNA = "always")) %>%
  addmargins()
#        
#          FALSE   TRUE   <NA>    Sum
#   FALSE  87941  39988      0 127929
#   TRUE   31778 167639      0 199417
#   <NA>     663    512   8255   9430
#   Sum   120382 208139   8255 336776

虽然我了解您要执行的操作,但它并没有将其转换为 R 语法。

只需执行以下操作之一:

dplyr::filter(flights, dep_delay < 2 & arr_delay < 2)
dplyr::filter(flights, dep_delay < 2, arr_delay < 2)

dplyr::filter默认为“AND”逻辑,因此您始终可以使用上面的第二种格式。确实,您需要开始使用Logic运算符的唯一时间是您在逻辑中的任何位置都需要“或”。


顺便说一句:要了解有关上述第 1 点的更多信息,请参阅

if (-1) 1 else 2
# [1] 1
if (0) 1 else 2
# [1] 2
if (1) 1 else 2
# [1] 1

推荐阅读