想象一下一张桌子,上面有一些警员的工作日期和时间。对于每个班次,我们都有初始日期时间和最终日期时间。例如,我想计算每年的小时数。我可以做到,但是由于在两年中不同时间的轮换,这是一项非常复杂的任务。有快速的方法吗?这似乎是一个很常见的任务,但是我找不到任何软件包可以做到这一点。例如,如果我想计算一周中的某天的工作时间,则我有同样的问题。有任何迹象吗?
数据:
library(tidyverse)
library(lubridate)
tabela <- tibble(
data_hora_chegada = c(
ymd_hms("2018-07-05 18:00:00"),
ymd_hms("2019-05-05 20:00:00"),
ymd_hms("2019-12-31 23:00:00")
),
data_hora_saida = c(
ymd_hms("2018-07-06 16:00:00"),
ymd_hms("2019-05-05 22:30:00"),
ymd_hms("2020-01-01 15:00:00")
)
)
tabela %>%
mutate(
intervalo = lubridate::interval(
data_hora_chegada,
data_hora_saida
)
) -> tabela
预期输出:
Year|Hours
2018| 22
2019| 3,5
2020| 15
# or similarly, with "Day of Week" instead of "Year"
为了考虑年份的变化正确地进行计算,基本上需要将记录分成两部分,然后可以像已经完成的那样进行intervalo的计算并进行汇总。
tabela.split <-
tabela %>%
rowwise() %>%
do(
{
my_row <- .
new_df <- data.frame(
ano = year(my_row$data_hora_chegada) : year(my_row$data_hora_saida)
) %>%
mutate(
data_hora_chegada = ISOdate(ano, 1, 1, 0, 0, 0),
data_hora_saida = ISOdate(ano+1, 1, 1, 0, 0, 0)
)
new_df[1, "data_hora_chegada"] <- my_row$data_hora_chegada
new_df[nrow(new_df), "data_hora_saida"] <- my_row$data_hora_saida
new_df
}
) %>%
ungroup()
print(tabela.split)
此代码可在任何间隔中使用,因此如果间隔中有一年以上,它将生成间隔中各年所需的记录。
输出
ano data_hora_chegada data_hora_saida
* <int> <dttm> <dttm>
1 2018 2018-07-05 18:00:00 2018-07-06 16:00:00
2 2019 2019-05-05 20:00:00 2019-05-05 22:30:00
3 2019 2019-12-31 23:00:00 2020-01-01 00:00:00
4 2020 2020-01-01 00:00:00 2020-01-01 15:00:00
现在您可以使用group_by()
和summarize()
来按年获取总计。
tabela.split %>%
mutate(
intervalo = as.numeric(lubridate::interval(
data_hora_chegada,
data_hora_saida
))
) %>%
mutate(Year = year(data_hora_chegada)) %>%
group_by(Year) %>%
summarise(Hours = round(sum(intervalo)/3600,1))
输出
Year Hours
<dbl> <dbl>
1 2018 22
2 2019 3.5
3 2020 15
现在要使其按动态指定的任何时间度量中断将是一项非常复杂的任务。