当R

时间:2019-05-09 20:31:08

标签: r loops tidyverse

我正在研究R4DS,目前正在进行5.6.7练习(https://r4ds.had.co.nz/transform.html#exercises-11)。

此处的数字1旨在考虑有关航班典型延误特性的一些情况。第一个子项目是“一次航班在50%的时间早15分钟,在50%的时间晚15分钟”。

我想在“ nycflights13”数据集中找到航班,这些航班的晚到达时间等于15分钟,早到达时间等于15分钟。

到目前为止,我创建了一个仅包含年,月,日,尾号和到达延迟的新数据框。我还使用dplyr进行了变异,并添加了“ 15_min_delay”和“ 15_min_early”逻辑列。

接下来,我使用plyr进行了过滤,以创建一个新的数据框,该数据框仅包含早15分钟或晚15分钟的航班。

在这里,我想按尾数进行分组,我发现我有大约2.7k唯一尾数,但我有9266个观测值。因此,我知道会重复一些尾巴。

创建r odd_delays_new后,我迷失了方向。我曾尝试创建一个带ifelse的for循环,以循环所有9,266个观测值,并向延迟计数器或早期计数器+1,但这给了我一个错误。

odd_delays <- flights %>%
  select(year, month, day, tailnum, arr_delay) %>%
  mutate("15_minute_delay" = arr_delay == 15, "15_minute_early" = arr_delay == -15)
length(odd_delays$"15_minute_delay"[odd_delays$"15_minute_delay" == TRUE])
length(odd_delays$"15_minute_early"[odd_delays$"15_minute_early" == TRUE])
odd_delays_new <- odd_delays %>%
  filter(odd_delays$`15_minute_delay` == TRUE | odd_delays$`15_minute_early` == TRUE)
  ifelse(odd_delays_new$`15_minute_delay` == TRUE, delay = delay + 1, early = early + 1)

我希望我的结果是3列数据框。第一列将包含尾号,第二列将包含飞机延迟15分钟到达的次数,第三列将包含飞机提前15分钟到达的次数。

1 个答案:

答案 0 :(得分:0)

我将分两部分回答。

  • 我将如何处理
  • for循环的替代方法。

解决问题

要回答您的问题,您可以停留在dplyr管道中。我认为这本书至少意味着早/晚15分钟,因此我使用了>=<=,并且您想了解延迟/提前到达量与总数的关系,因此您需要首先找到分母。 n()是基于分组的观察数。然后,在这些逻辑结果上使用sum()。如果您要求sum()或进行其他数学运算,R会将逻辑值视为0,1。

off_schedule <-
  flights %>%
  group_by(tailnum) %>% 
  summarise(
    n = n(),
    delay_15min = sum(arr_delay >= 15, na.rm = TRUE),
    early_15min = sum(arr_delay <= -15, na.rm = TRUE)
  ) %>% 
  ungroup() %>% 
  mutate(
    delay_pct = delay_15min/n*100,
    early_pct = early_15min/n*100,
    off_pct = delay_pct + early_pct
  )

这为我们提供了下表:

# tailnum       n delay_15min early_15min delay_pct early_pct off_pct
#   <chr>   <int>       <int>       <int>     <dbl>     <dbl>   <dbl>
#  D942DN      4           2           0     50          0      50  
#  N0EGMQ    371          95          73     25.6       19.7    45.3
#  N10156    153          51          34     33.3       22.2    55.6
#  N102UW     48           7          13     14.6       27.1    41.7
#  N103US     46           2          13      4.35      28.3    32.6

for循环

要使循环正常工作,必须使用索引值。

for (i in 1:nrow(odd_delays)){  
  if(odd_delays_new$`15_minute_delay`[i] == TRUE){
    odd_delays_new$delay[i] <- odd_delays_new$delay[i-1] + 1
  } 

  if(odd_delays_new$`15_minute_early`[i] == TRUE){
    odd_delays_new$early[i] <- odd_delays_new$early[i-1] + 1
  } 
}

三年后写作或阅读都不好玩。幸运的是,cumsum()函数可以对它们进行计数:

df <-
  odd_delays_new %>% 
  group_by(tailnum) %>% 
  mutate(
    delay = cumsum(`15_minute_delay`),
    early = cumsum(`15_minute_early`)
  ) %>% 
  ungroup()

但是,该解决方案无法帮助您了解N0EGMQ的航班延误的频率,而只是告诉您N0EGMQ航班的延误,有多少延误与提前到达。

我希望这会有所帮助。