【问题标题】:Why do parenthesis break my dplyr::filter() output?为什么括号会破坏我的 dplyr::filter() 输出?
【发布时间】:2020-07-16 18:29:18
【问题描述】:

当我遇到一个奇怪的结果时,我正在使用 R4DS 并了解 filter() 函数。我试图 filtertibble 只找到 dep_delayarr_delay 不到 2 分钟的观察结果。这是我的代表:

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 &amp; arr_delay) 转换为TRUE1 但实际上会产生完全不同的输出。谁能帮我理解发生了什么?

【问题讨论】:

    标签: r filter dplyr


    【解决方案1】:

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

    dep_delay &amp; arr_delay &lt; 2 是两个独立的逻辑条件。

    1. dep_delay,实际上是(dep_delay != 0)
    2. arr_delay &gt; 2,这是不言而喻的。

    事实上,flights 中只有 167,639 行,其中 dep_delayarr_delay 不是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
    

    【讨论】:

    • 然而,我仍然不明白我最初的命令是问 R 什么。这纯粹是荒谬的吗?因为filter(flights, dep_delay != 0 | arr_delay &gt; 2) 给了我 316,375 行,这比我的初始命令少。其他行是N/A 吗?我知道我的初始命令基本上是错误的做事方式,但不明白 R 的想法让我很烦。
    • filter 正在为您删除 NA 值。请参阅 table(is.na(filter(flights, dep_delay != 0 | arr_delay &gt; 2)$dep_delay))table(is.na(flights$dep_delay)) 以了解这一点。 “荒谬”?并非如此,R 将其解释为某种东西,而不是您想要的。有时使用if (12) 很好......虽然事实上我觉得它有点草率,因为有一些推论 我们 直观地做出 R 没有。
    • with(flights, table(dep_delay != 0 | arr_delay &gt; 2, useNA = "always")) 向您显示filter 为您提供的316375,并解释说8303 是NA,因为任何包含NA(未处理)的逻辑操作都是NA 本身(而不是真假)。
    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2013-06-25
    • 2013-06-07
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多