我有一个案例表。每一行代表一个案例。case有一个Case_id、一个开始日期、一个完成日期和其他属性。案件在其开始日期和完成日期之间是有效的。这是一个表达式:
library(tidyverse)
set.seed(42)
Case_id <- seq(1:100)
Start <- sample(seq(as.Date("2022-08-01"), as.Date("2022-12-01"), by = "day"), 100, replace = TRUE)
Complete <- Start + sample(0:60, 1, replace = TRUE)
Other_attributes <- sample(c("Red", "Blue", "Green"), 100, replace = TRUE)
Cases <- tibble(Case_id, Start, Complete, Other_attributes)
head(Cases)
#> # A tibble: 6 × 4
#> Case_id Start Complete Other_attributes
#> <int> <date> <date> <chr>
#> 1 1 2022-09-18 2022-10-11 Red
#> 2 2 2022-11-09 2022-12-02 Blue
#> 3 3 2022-10-04 2022-10-27 Red
#> 4 4 2022-08-25 2022-09-17 Blue
#> 5 5 2022-10-13 2022-11-05 Green
#> 6 6 2022-11-08 2022-12-01 Red
创建于2023-01-01使用reprex v2.0.2
最后,我想展示活动病例的数量是如何随着时间的推移而发展的,可能按其他属性的任何组合进行分组。随着时间推移的发展由每周参考日期表示。在本例中,我将引用日期放入一个向量中,但它们也可以组织成一个包含一列的索引。
Reference_dates <- seq(as.Date("2022-09-04"), as.Date("2022-12-31"), by = "weeks")
为了实现我的最终目标,我将首先创建一个长表。我遍历每周引用日期的每个元素,并过滤在每个引用日期活动的案例。在第一个参考日期对活动案例的过滤可以如下所示:
Cases %>% filter(Reference_dates[1] >= Start & Reference_dates[1] <= Complete)
过滤后的case还应该通过包含相应引用日期的新列来充实。
我对每个引用日期重复此操作,然后将过滤和充实的用例行绑定到一个更长的平面表中。我的问题是如何创建这个长表.
我想避免for
循环,而是使用函数式编程来创建长表。我已经研究了列表列与随后的解嵌套和purrr::map()
与随后的purrr::list_rbind()
,但我不知道如何开始。什么好主意吗?
一旦解决了这个问题,我就可以很容易地使用rpivottable()
或group_by(Reference_dates, Other_attributes)
来计算每个引用日期的活动案例数量,并通过其他属性的任何组合对其进行分组。
我的真实案例数实际上要大得多,而且我还有其他一些属性。请告知是否有比首先创建长表更有效的方法来实现我的最终目标。
使用purrr::map_df
,你可以循环你的参考日期,创建你的过滤数据集,并将它们绑定到一个df在一个步骤,像这样:
library(tidyverse)
map_df(Reference_dates, function(x) {
Cases %>%
filter(x >= Start & x <= Complete) %>%
mutate(Reference_Date = x)
})
#> # A tibble: 275 × 5
#> Case_id Start Complete Other_attributes Reference_Date
#> <int> <date> <date> <chr> <date>
#> 1 4 2022-08-25 2022-09-17 Blue 2022-09-04
#> 2 7 2022-08-18 2022-09-10 Red 2022-09-04
#> 3 11 2022-08-24 2022-09-16 Green 2022-09-04
#> 4 17 2022-08-20 2022-09-12 Red 2022-09-04
#> 5 18 2022-08-26 2022-09-18 Red 2022-09-04
#> 6 24 2022-08-27 2022-09-19 Red 2022-09-04
#> 7 31 2022-09-03 2022-09-26 Blue 2022-09-04
#> 8 38 2022-08-24 2022-09-16 Blue 2022-09-04
#> 9 39 2022-08-30 2022-09-22 Red 2022-09-04
#> 10 41 2022-08-15 2022-09-07 Red 2022-09-04
#> # … with 265 more rows
不是purrr
解决方案,而是dplyr
解决方案。
library(tidyverse)
columnsToAdd <- as.character(Reference_dates)
Cases[,columnsToAdd] <- ""
Cases |>
pivot_longer(cols = starts_with('2022')) |>
mutate(name = as.Date(name)) |>
select(-value) |>
filter((name >= Start & name <= Complete))
#> # A tibble: 275 × 5
#> Case_id Start Complete Other_attributes name
#> <int> <date> <date> <chr> <date>
#> 1 1 2022-09-18 2022-10-11 Red 2022-09-18
#> 2 1 2022-09-18 2022-10-11 Red 2022-09-25
#> 3 1 2022-09-18 2022-10-11 Red 2022-10-02
#> 4 1 2022-09-18 2022-10-11 Red 2022-10-09
#> 5 2 2022-11-09 2022-12-02 Blue 2022-11-13
#> 6 2 2022-11-09 2022-12-02 Blue 2022-11-20
#> 7 2 2022-11-09 2022-12-02 Blue 2022-11-27
#> 8 3 2022-10-04 2022-10-27 Red 2022-10-09
#> 9 3 2022-10-04 2022-10-27 Red 2022-10-16
#> 10 3 2022-10-04 2022-10-27 Red 2022-10-23
#> # … with 265 more rows