Это можно сделать, используя fuzzyjoin
:
library(dplyr)
df <- tribble(
~id, ~date, ~min,
1, "2015-07-18", 25,
1, "2015-07-22", 15,
1, "2015-07-23", 10,
1, "2015-07-30", 15,
2, "2015-07-10", 10,
2, "2015-07-16", 20,
2, "2015-07-23", 10
) %>%
mutate(date = as.Date(date))
Мы объединим df
с собой по id
и date
, выбрав строки из второго df
, где id
то же самое, а вторая date
находится между первой датой и первой датой - 7.
library(fuzzyjoin)
df_join <-
fuzzy_left_join(
df, df,
by = c("id", "date"),
match_fun = c(
"id" = `==`,
"date" = function(x, y) {y <= x & y >= x - 7}
)
)
df_join
#> # A tibble: 13 x 6
#> id.x date.x min.x id.y date.y min.y
#> <dbl> <date> <dbl> <dbl> <date> <dbl>
#> 1 1 2015-07-18 25 1 2015-07-18 25
#> 2 1 2015-07-22 15 1 2015-07-18 25
#> 3 1 2015-07-22 15 1 2015-07-22 15
#> 4 1 2015-07-23 10 1 2015-07-18 25
#> 5 1 2015-07-23 10 1 2015-07-22 15
#> 6 1 2015-07-23 10 1 2015-07-23 10
#> 7 1 2015-07-30 15 1 2015-07-23 10
#> 8 1 2015-07-30 15 1 2015-07-30 15
#> 9 2 2015-07-10 10 2 2015-07-10 10
#> 10 2 2015-07-16 20 2 2015-07-10 10
#> 11 2 2015-07-16 20 2 2015-07-16 20
#> 12 2 2015-07-23 10 2 2015-07-16 20
#> 13 2 2015-07-23 10 2 2015-07-23 10
Теперь нам нужно сгруппировать по идентификатору и первой дате и вычислить общее количество минут.
res <-
df_join %>%
select(id = id.x, date = date.x, min.x, min.y) %>%
group_by(id, date) %>%
summarise(min = first(min.x), totmin = sum(min.y))
res
#> # A tibble: 7 x 4
#> # Groups: id [2]
#> id date min totmin
#> <dbl> <date> <dbl> <dbl>
#> 1 1 2015-07-18 25 25
#> 2 1 2015-07-22 15 40
#> 3 1 2015-07-23 10 50
#> 4 1 2015-07-30 15 25
#> 5 2 2015-07-10 10 10
#> 6 2 2015-07-16 20 30
#> 7 2 2015-07-23 10 30