Reputation: 79
I've been wrapping my head around this question. So my task is to convert the data from a monthly basis to a weekly basis (Sunday to Sat would be each week). The data looks like this:
Name | Meal | Food | date from | date to |
---|---|---|---|---|
Albert | lunch | apple | 30/05/2021 | 26/06/2021 |
Lucas | dinner | banana | 30/05/2021 | 26/06/2021 |
John | lunch | grape | 30/05/2021 | 26/06/2021 |
The Weekly buckets would look like this:
Name | Meal | Food | date from | date to |
---|---|---|---|---|
Albert | lunch | apple | 1/06/2021 | 5/06/2021 |
Albert | lunch | apple | 6/06/2021 | 12/06/2021 |
Albert | lunch | apple | 13/06/2021 | 19/06/2021 |
Albert | lunch | apple | 20/06/2021 | 26/06/2021 |
Lucas | dinner | banana | 1/06/2021 | 5/06/2021 |
Lucas | dinner | banana | 6/06/2021 | 12/06/2021 |
Lucas | dinner | banana | 13/06/2021 | 19/06/2021 |
Lucas | dinner | banana | 20/06/2021 | 26/06/2021 |
John | lunch | grape | 1/06/2021 | 5/06/2021 |
John | lunch | grape | 6/06/2021 | 12/06/2021 |
John | lunch | grape | 13/06/2021 | 19/06/2021 |
John | lunch | grape | 20/06/2021 | 26/06/2021 |
I'm lost to start, any help would be appreciated.
Upvotes: 0
Views: 270
Reputation: 21908
I decided to write a custom function for this purpose:
library(dplyr)
library(lubridate)
library(tidyr)
fn <- function(x, y) {
stopifnot(is.Date(x))
stopifnot(is.Date(y))
intv <- floor(interval(x, y) / weeks(1))
a <- x + (0:intv) * 7
b <- a + days(6)
a[1] <- round_date(a[1], unit = "month")
dts <- tibble(start = a, end = b)
dts
}
# Then we test our function with a pair of dates
fn(ymd("2021-05-30"), ymd("2021-06-26"))
# A tibble: 4 x 2
start end
<date> <date>
1 2021-06-01 2021-06-05
2 2021-06-06 2021-06-12
3 2021-06-13 2021-06-19
4 2021-06-20 2021-06-26
Then we apply our function to our original data set:
DF %>%
mutate(across(starts_with("date"), ~ dmy(.x))) %>%
rowwise() %>%
mutate(output = list(fn(date_from, date_to))) %>%
unnest(output) %>%
select(!starts_with("date"))
# A tibble: 12 x 5
Name Meal Food start end
<chr> <chr> <chr> <date> <date>
1 Albert lunch apple 2021-06-01 2021-06-05
2 Albert lunch apple 2021-06-06 2021-06-12
3 Albert lunch apple 2021-06-13 2021-06-19
4 Albert lunch apple 2021-06-20 2021-06-26
5 Lucas dinner banana 2021-06-01 2021-06-05
6 Lucas dinner banana 2021-06-06 2021-06-12
7 Lucas dinner banana 2021-06-13 2021-06-19
8 Lucas dinner banana 2021-06-20 2021-06-26
9 John lunch grape 2021-06-01 2021-06-05
10 John lunch grape 2021-06-06 2021-06-12
11 John lunch grape 2021-06-13 2021-06-19
12 John lunch grape 2021-06-20 2021-06-26
Upvotes: 2