【问题标题】:Increment a Counter when TRUE value in Logical Column in R当 R 中逻辑列中的值为 TRUE 时增加计数器
【发布时间】:2019-09-27 17:52:36
【问题描述】:

我正在研究 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 分钟的航班。

从这里开始,我想对 tailnums 进行分组,我发现我有大约 2.7k 个独特的 tailnums,但我有 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 分钟到达的次数。

【问题讨论】:

  • 你不想按航班而不是tailnum分组吗?另外,我会研究 dplyr::summarise()。

标签: r loops tidyverse


【解决方案1】:

我将分两部分回答这个问题。

  • 我将如何处理这个问题
  • for 循环的替代方案。

解决问题

要回答您的问题,您可以留在dplyr 管道内。我相信这本书意味着至少提前/迟到了 15 分钟,所以我使用了&gt;=&lt;=,你想了解延迟/早到与总数的关系,所以你需要先找到你的分母。 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
  } 
}

3年后写不读也不好玩。幸运的是,cumsum() 函数可以统计它们:

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

但是,此解决方案无法帮助您了解 N0EGMQ 的航班延误频率,它只是告诉您航班延误的 N0EGMQ 航班,延误与提前到达的次数。

我希望这会有所帮助。

【讨论】:

  • 你太棒了。这绝对是我一直在寻找的。感谢您抽出宝贵的时间来说明 1)作为一种不同的方式来解决我的问题,以及 2)解决我遇到的最初问题。我没有足够的代表来投赞成票,但我确实做到了。
猜你喜欢
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 2021-11-18
  • 2021-11-06
  • 1970-01-01
  • 2022-07-06
  • 2020-11-03
  • 1970-01-01
相关资源
最近更新 更多