Вот решение, которое расширяет интервалы start_time
и end_time
на 30 minute
и подсчитывает результат.
library(tidyverse)
library(lubridate)
df <- tibble(
client = c("smith", "coven", "peter"),
start_time = c("08:00", "09:30", "07:35"),
end_time = c("10:15", "10:25", "11:30")
)
df %>%
mutate(
start_time = floor_date(as.POSIXct(start_time, format = '%H:%M', tz = 'UTC'), unit = '10 minutes'),
end_time = floor_date(as.POSIXct(end_time, format = '%H:%M', tz = 'UTC'), unit = '10 minutes'),
) %>%
nest(start_time, end_time) %>%
mutate(time = map(data, ~seq(unique(.x$start_time), unique(.x$end_time), unit = 'min', by = '30 min'))) %>%
unnest(time) %>%
mutate(time = format(time, '%H:%M')) %>%
group_by(time) %>%
tally()
# A tibble: 9 x 2
time n
<chr> <int>
1 07:30 1
2 08:00 2
3 08:30 2
4 09:00 2
5 09:30 3
6 10:00 3
7 10:30 1
8 11:00 1
9 11:30 1
Если вам нужен полный интервал времени от 07:00 to 11:30
, вы можете сделать следующее:
df %>%
mutate(
start_time = floor_date(as.POSIXct(start_time, format = "%H:%M", tz = "UTC"), unit = "10 minutes"),
end_time = floor_date(as.POSIXct(end_time, format = "%H:%M", tz = "UTC"), unit = "10 minutes"),
) %>%
nest(start_time, end_time) %>%
mutate(time = map(data, ~ seq(unique(.x$start_time), unique(.x$end_time), unit = 'min', by = '30 min'))) %>%
unnest(time) %>%
mutate(time = format(time, "%H:%M")) %>%
group_by(time) %>%
tally() %>%
right_join( # add full sequence of time intervals
tibble(time = seq(
as.POSIXct("07:00", format = "%H:%M", tz = "UTC"),
as.POSIXct("11:30", format = "%H:%M", tz = "UTC"),
unit = 'min', by = '30 min'
)) %>%
mutate(time = format(time, "%H:%M")),
by = 'time'
)
# A tibble: 10 x 2
time n
<chr> <int>
1 07:00 NA
2 07:30 1
3 08:00 2
4 08:30 2
5 09:00 2
6 09:30 3
7 10:00 3
8 10:30 1
9 11:00 1
10 11:30 1