聚合具有重叠日期范围的行的列值
Aggregate column values of rows that have overlapping range of dates
我有一个如下所示的数据框:
person date1 date2 total amount overlap
A 2019-03-01 2019-03-16 50
A 2019-03-10 2019-03-31 100
A 2019-03-20 2019-03-31 70
B 2019-03-01 2019-03-12 200
B 2019-03-01 2019-03-20 130
B 2019-03-16 2019-03-31 100
我想创建一个新列(重叠),它采用日期范围与日期范围重叠的每一行加上同一组中其他行的值(这里我想按人员列分组)当前行的。
为了说明这一点,第一行应该是 50(当前行的值)加上 100(因为第二行与第一行重叠)所以我们总共得到 150。这里,请注意我们没有t 包括第三行,因为第三行的日期范围与第一行不重叠。
我尝试执行 group_by(person) 然后 mutate(overlap) 但我不知道如何访问同一组中的其他行以了解它们是否与当前行重叠。我也尝试研究 Overlap() 函数,但我不确定如何利用它来获得我想要的东西。
理想情况下,我想制作一个看起来像这样的 table:
person date1 date2 total amount overlap
A 2019-03-01 2019-03-16 50 150
A 2019-03-10 2019-03-31 100 220
A 2019-03-20 2019-03-31 70 170
B 2019-03-01 2019-03-12 200 330
B 2019-03-01 2019-03-20 130 430
B 2019-03-16 2019-03-31 100 230
我们可以group_by
Person
做total_amount
的sum
位于between
date1
和date2
。
library(dplyr)
df %>%
mutate_at(vars(starts_with("date")), as.Date) %>%
group_by(person) %>%
mutate(overlap = purrr::map2_dbl(date1, date2,
~sum(total_amount[between(date1, .x, .y) | between(date2, .x, .y)])))
# person date1 date2 total_amount overlap
# <fct> <date> <date> <int> <dbl>
#1 A 2019-03-01 2019-03-16 50 150
#2 A 2019-03-10 2019-03-31 100 220
#3 A 2019-03-20 2019-03-31 70 170
#4 B 2019-03-01 2019-03-12 200 330
#5 B 2019-03-01 2019-03-20 130 430
#6 B 2019-03-16 2019-03-31 100 230
数据
df <- structure(list(person = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("A",
"B"), class = "factor"), date1 = structure(c(1L, 2L, 4L, 1L,
1L, 3L), .Label = c("2019-03-01", "2019-03-10", "2019-03-16",
"2019-03-20"), class = "factor"), date2 = structure(c(2L, 4L,
4L, 1L, 3L, 4L), .Label = c("2019-03-12", "2019-03-16", "2019-03-20",
"2019-03-31"), class = "factor"), total_amount = c(50L, 100L,
70L, 200L, 130L, 100L)), class = "data.frame", row.names = c(NA, -6L))
我有一个如下所示的数据框:
person date1 date2 total amount overlap
A 2019-03-01 2019-03-16 50
A 2019-03-10 2019-03-31 100
A 2019-03-20 2019-03-31 70
B 2019-03-01 2019-03-12 200
B 2019-03-01 2019-03-20 130
B 2019-03-16 2019-03-31 100
我想创建一个新列(重叠),它采用日期范围与日期范围重叠的每一行加上同一组中其他行的值(这里我想按人员列分组)当前行的。
为了说明这一点,第一行应该是 50(当前行的值)加上 100(因为第二行与第一行重叠)所以我们总共得到 150。这里,请注意我们没有t 包括第三行,因为第三行的日期范围与第一行不重叠。
我尝试执行 group_by(person) 然后 mutate(overlap) 但我不知道如何访问同一组中的其他行以了解它们是否与当前行重叠。我也尝试研究 Overlap() 函数,但我不确定如何利用它来获得我想要的东西。
理想情况下,我想制作一个看起来像这样的 table:
person date1 date2 total amount overlap
A 2019-03-01 2019-03-16 50 150
A 2019-03-10 2019-03-31 100 220
A 2019-03-20 2019-03-31 70 170
B 2019-03-01 2019-03-12 200 330
B 2019-03-01 2019-03-20 130 430
B 2019-03-16 2019-03-31 100 230
我们可以group_by
Person
做total_amount
的sum
位于between
date1
和date2
。
library(dplyr)
df %>%
mutate_at(vars(starts_with("date")), as.Date) %>%
group_by(person) %>%
mutate(overlap = purrr::map2_dbl(date1, date2,
~sum(total_amount[between(date1, .x, .y) | between(date2, .x, .y)])))
# person date1 date2 total_amount overlap
# <fct> <date> <date> <int> <dbl>
#1 A 2019-03-01 2019-03-16 50 150
#2 A 2019-03-10 2019-03-31 100 220
#3 A 2019-03-20 2019-03-31 70 170
#4 B 2019-03-01 2019-03-12 200 330
#5 B 2019-03-01 2019-03-20 130 430
#6 B 2019-03-16 2019-03-31 100 230
数据
df <- structure(list(person = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("A",
"B"), class = "factor"), date1 = structure(c(1L, 2L, 4L, 1L,
1L, 3L), .Label = c("2019-03-01", "2019-03-10", "2019-03-16",
"2019-03-20"), class = "factor"), date2 = structure(c(2L, 4L,
4L, 1L, 3L, 4L), .Label = c("2019-03-12", "2019-03-16", "2019-03-20",
"2019-03-31"), class = "factor"), total_amount = c(50L, 100L,
70L, 200L, 130L, 100L)), class = "data.frame", row.names = c(NA, -6L))