根据小球的条件进行变异或过滤

时间:2018-07-21 04:37:01

标签: r dplyr left-join mutate

我目前正在研究R for Data Science,尤其是练习5.7.1 #8,它正在分析library(nycflights13)数据包数据。

问题如下:

  
      
  1. 对于每架飞机,计算第一次延迟超过1小时之前的飞行次数。
  2.   

我的尝试是通过使用first()函数创建一个表来查找第一个“超过60分钟”的延迟:

first_del <- flights %>%
  select(month, day, flight, dep_time, tailnum, dep_delay) %>%
  filter(dep_delay > 60) %>%
  group_by(month,day) %>%
  arrange(month, day, dep_time) %>%
  summarise(flight = first(flight), first_time = first(dep_time))

first_del

# A tibble: 365 x 4
# Groups:   month [?]
    month   day flight first_time
    <int> <int>  <int>      <int>
 1     1     1   4576        811
 2     1     2     22        126
 3     1     3    104         50
 4     1     4    608        106
 5     1     5     11         37
 6     1     6     27        746
 7     1     7    145        756
 8     1     8   4334        740
 9     1     9     51        641
10     1    10    905        743
# ... with 355 more rows

我的想法是,如果flights标题1中的每一行与月,日匹配,并且小于当天的第一次延误航班的航班号(例如,从{ {1}}稍作调整,航班4576是1月1日的首个“超过60分钟的延迟”航班,在此之前的所有其他航班都将计算在内)。所需的输出将类似于:

first_del

理想情况下,每天根据 flights %>% filter(dep_time > 805) %>% select(month, day, flight, dep_time, tag) # A tibble: 272,933 x 4 month day flight dep_time tag <int> <int> <int> <int> <int> 1 1 1 269 807 1 2 1 1 4388 809 1 3 1 1 3538 810 1 4 1 1 2395 810 1 5 1 1 4260 811 1 6 1 1 4576 811 1 7 1 1 675 811 0 8 1 1 4537 812 0 9 1 1 914 813 0 10 1 1 346 814 0 小标题对所有行数小于或等于航班号的行进行计数会很棒。我尝试使用过滤器的许多组合,%in%,突变,但尚未成功。我应该创建一个自定义函数吗?

我最终想要的输出是(具有虚拟 first_del值):

$count

其中 first_del # A tibble: 365 x 4 # Groups: month [?] month day flight first_time count <int> <int> <int> <int> <int> 1 1 1 4576 811 212 2 1 2 22 126 216 3 1 3 104 50 298 4 1 4 608 106 220 5 1 5 11 37 168 6 1 6 27 746 287 7 1 7 145 756 302 8 1 8 4334 740 246 9 1 9 51 641 235 10 1 10 905 743 313 是当天第一班延误航班之前的飞行次数(如上面链接中的问题所希望的那样)。

2 个答案:

答案 0 :(得分:0)

您可以在逻辑向量上使用which.max来确定满足条件的第一个实例。您还需要检查实际发生的情况。

library(dplyr)
library(nycflights13)

flights %>%
  mutate(dep_delay = coalesce(dep_delay, 0)) %>%
  arrange(month, day, dep_time) %>%
  group_by(tailnum) %>%
  summarise(max_delay = max(dep_delay), 
            which_first_geq_1hr = which.max(dep_delay > 60)) %>%
  ungroup %>%
  filter(max_delay > 60)

我假设延迟意味着出发延迟,NA延迟意味着0或至少少于一个小时,而我忽略了“未能”延迟超过一个小时的飞机。 coalesce是避免which.max(NA)所必需的。

答案 1 :(得分:0)

问题是每架飞机,所以您真的想按tailnum分组进行操作。您可以添加一个标志列,但实际上您最终需要传递给filter(逻辑向量)或slice(行索引的向量)。有多种方法可以做到这一点,例如slice(seq(c(which(dep_delay > 60) - 1, n())[1])),但是一种不错的方法是使用dplyr的cumallall的累积版本,例如cumsumsum)来生成逻辑向量filter

library(dplyr)

nycflights13::flights %>% 
    group_by(tailnum) %>% 
    arrange(year, month, day, dep_time) %>%    # ensure order before cumany
    filter(cumall(pmax(dep_delay, arr_delay) < 60)) %>% 
    tally()    # count number of observations per group (tailnum)
#> # A tibble: 3,709 x 2
#> # Groups:   tailnum [3,709]
#>    tailnum     n
#>    <chr>   <int>
#>  1 N10156      9
#>  2 N102UW     25
#>  3 N103US     46
#>  4 N104UW      3
#>  5 N105UW     22
#>  6 N107US     20
#>  7 N108UW     36
#>  8 N109UW     28
#>  9 N110UW     15
#> 10 N11107      7
#> # ... with 3,699 more rows

可以创建一个中间表,其中包含前几个大延迟,并在它们所在的位置进行ID的自联接,或者使用if_else向某些观测值添加标志值,但是无论如何,将子集设置为这些行将仍然需要与以上cumall类似的逻辑,因此它们实际上只是更长,更慢的方法。