【问题标题】:Counting number of rows before the first event and after the last event in another dataframe计算另一个数据框中第一个事件之前和最后一个事件之后的行数
【发布时间】:2021-10-05 00:14:23
【问题描述】:

我想基于以下两个数据框创建一个新的数据框(reports_before_after_AC_clusters):

  1. AC 事件数据框
tail(AC_clusters)
  Park                  Date        Cluster 
  <chr>                 <date>        <dbl>    
1 Arbour Lake East      2019-07-08       1       
2 Arbour Lake East      2019-07-09       1       
3 Arbour Lake East      2019-07-10       1       
4 Winston-Victoria Park 2021-07-09       1       
5 Winston-Victoria Park 2021-09-10       2       
6 Winston-Victoria Park 2021-09-16       2

其中“Park”是举办 AC 活动的公园,“cluster”代表一组 AC 活动,其中每个活动距离上一个活动不到 30 天。

  1. 报告数据框
tail(Reports_per_park_per_day_2)
  Park                   Date    
  <chr>                  <date>    
1 Arbour Lake East       2019-07-02       
2 Arbour Lake East       2019-07-05      
3 Arbour Lake East       2019-07-20       
4 Winston-Victoria Park  2021-07-02       
5 Winston-Victoria Park  2021-09-08       
6 Winston-Victoria Park  2021-09-22

此数据框中的公园与上一个数据框中的公园相同,但报告未分类。

我想创建一个新的数据框,其中包括发生 AC 事件的公园、AC 事件的集群(例如 1)、集群中第一个 AC 事件的日期(数据框 1)、集群中最后一个 AC 事件的日期(数据框 1),该集群中 AC 事件的数量(数据框 1),该集群中第一个 AC 事件前 2 周的报告数量(数据框 1 和 2),以及该集群中最后一个 AC 事件后 2 周的报告数量(数据框 1 和 2)。

根据上面提供的数据框,我想要的数据框应该如下所示:

#reports_before_after_AC_clusters#

Park                   Cluster   Start_date End_date   Number_AC Number_reports_before Number_reports_after
Arbour Lake East       1         2019-07-08 2019-07-10 3         2                     1      
Winston-Victoria Park  1         2021-07-09 2021-07-09 1         1                     0
Winston-Victoria Park  2         2021-09-10 2021-09-16 2         1                     1    

【问题讨论】:

  • 到目前为止你尝试过什么?您是方言不可知论者,还是更喜欢 tidyverse 或 base R 或 data.table 或 ...?
  • 我喜欢 tidyverse!我没有尝试太多。我是 R 新手,所以任何建议都将不胜感激!

标签: r


【解决方案1】:

你可以使用

library(lubridate)
library(dplyr)

AC_clusters %>% 
  group_by(Park, Cluster) %>% 
  mutate(Start_date = min(Date), 
            End_date = max(Date)) %>% 
  group_by(Park, Cluster, Start_date, End_date) %>% 
  summarise(Number_AC = n(), .groups = "drop") %>% 
  left_join(Reports_per_park_per_day_2, by = "Park") %>% 
  group_by(Park, Cluster, Start_date, End_date, Number_AC) %>% 
  summarise(Number_reports_before = sum(Date <= Start_date - weeks(2)),
            Number_reports_after  = sum(Date >= End_date + weeks(2)),
            .groups = "drop")

返回

# A tibble: 3 x 7
  Park                  Cluster Start_date End_date   Number_AC Number_reports_before Number_reports_after
  <chr>                   <dbl> <date>     <date>         <int>                 <int>                <int>
1 Arbour Lake East            1 2019-07-08 2019-07-10         3                     0                    0
2 Winston-Victoria Park       1 2021-07-09 2021-07-09         1                     0                    2
3 Winston-Victoria Park       2 2021-09-10 2021-09-16         2                     1                    0

这几乎是您的预期输出。但还是有一些疑问:

  • 如何计算集群 1 中 Winston-Victoria Park 的 Number_reports_before?为什么是 2 而不是 0?
  • 您如何准确计算 Number_reports_after?

如果我们从上面的代码中删除 + weeks(2)- weeks(2) 部分,输出将变为

# A tibble: 3 x 7
  Park                  Cluster Start_date End_date   Number_AC Number_reports_before Number_reports_after
  <chr>                   <dbl> <date>     <date>         <int>                 <int>                <int>
1 Arbour Lake East            1 2019-07-08 2019-07-10         3                     2                    1
2 Winston-Victoria Park       1 2021-07-09 2021-07-09         1                     1                    2
3 Winston-Victoria Park       2 2021-09-10 2021-09-16         2                     2                    1

这与您的预期结果很接近,但仍然不同。

编辑

代码的小改动:

AC_clusters %>% 
  group_by(Park, Cluster) %>% 
  mutate(Start_date = min(Date), 
         End_date = max(Date)) %>% 
  group_by(Park, Cluster, Start_date, End_date) %>% 
  summarise(Number_AC = n(), .groups = "drop") %>% 
  left_join(Reports_per_park_per_day_2, by = "Park") %>% 
  group_by(Park, Cluster, Start_date, End_date, Number_AC) %>% 
  summarise(Number_reports_before = sum(Date <= Start_date & Date >= Start_date - weeks(2)),
            Number_reports_after  = sum(Date >= End_date & Date <= End_date + weeks(2)),
            .groups = "drop")

返回

# A tibble: 3 x 7
  Park                  Cluster Start_date End_date   Number_AC Number_reports_before Number_reports_after
  <chr>                   <dbl> <date>     <date>         <int>                 <int>                <int>
1 Arbour Lake East            1 2019-07-08 2019-07-10         3                     2                    1
2 Winston-Victoria Park       1 2021-07-09 2021-07-09         1                     1                    0
3 Winston-Victoria Park       2 2021-09-10 2021-09-16         2                     1                    1

数据

AC_clusters <- structure(list(Park = c("Arbour Lake East", "Arbour Lake East", 
"Arbour Lake East", "Winston-Victoria Park", "Winston-Victoria Park", 
"Winston-Victoria Park"), Date = structure(c(18085, 18086, 18087, 
18817, 18880, 18886), class = "Date"), Cluster = c(1, 1, 1, 1, 
2, 2)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

Reports_per_park_per_day_2 <- structure(list(Park = c("Arbour Lake East", "Arbour Lake East", 
"Arbour Lake East", "Winston-Victoria Park", "Winston-Victoria Park", 
"Winston-Victoria Park"), Date = structure(c(18079, 18082, 18097, 
18810, 18878, 18892), class = "Date")), row.names = c(NA, -6L
), class = c("tbl_df", "tbl", "data.frame"))

【讨论】:

  • 这几乎可以工作,但是正如您自己强调的那样,Number_reports_after 似乎有问题。 Number_reports_after 是集群内最后一次 AC 事件后最多 2 周的报告数。但是,当我将您建议的代码应用于我的数据时,看起来 Number_reports_after 总结了公园内的所有报告,即使我离开 Date >= End_date + week(2)。你知道为什么会这样吗?
  • @Gab_Laj 编辑了代码(参见编辑)并修复了一个错误。
  • 这适用于编辑,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多