我有一个包含两个日期时间列的数据集:Begin&End:

library(tidyverse)

df <- tibble(
  Group = c("A", "B", "C"),
  Begin = as_datetime(c("2023-07-15 01:40:11", "2023-07-22 05:54:44", "2023-08-05 16:43:09")),
  End = as_datetime(c("2023-07-15 13:43:15", "2023-07-25 10:50:45", "2023-08-06 10:42:12"))
)

df
# A tibble: 3 × 3
  Group Begin               End                
  <chr> <dttm>              <dttm>             
1 A     2023-07-15 01:40:11 2023-07-15 13:43:15
2 B     2023-07-22 05:54:44 2023-07-25 10:50:45
3 C     2023-08-05 16:43:09 2023-08-06 10:42:12

The period between these two timestamps can be several days. Begin & End, on the other hand, can also be the same day. Now I want to split this time sequence into several days.
The days between Begin & End are "full" days and therefore start at 00:00:00 and end at 23:59:59.
I think this desired output illustrates what I want exactly:
(I only added the Group column for better illustration and it is not relevant for programming for now).

# A tibble: 7 × 3
  Group Begin               End                
  <chr> <dttm>              <dttm>             
1 A     2023-07-15 01:40:11 2023-07-15 13:43:15
2 B     2023-07-22 05:54:44 2023-07-22 23:59:59
3 B     2023-07-23 00:00:00 2023-07-23 23:59:59
4 B     2023-07-24 00:00:00 2023-07-24 23:59:59
5 B     2023-07-25 00:00:00 2023-07-25 10:50:45
6 C     2023-08-05 16:43:09 2023-08-05 23:59:09
7 C     2023-08-06 00:00:00 2023-08-06 10:42:12

Can anyone help me find a solution?
I think the difficulty is to keep the Begin-timestamp of the first day and the End-timestamp of the last day.

推荐答案

df |>
  # create a date column for beginning and end, for ease of use
  mutate(b = as.Date(Begin), e = as.Date(End),
        # create a sequence of dates between begin and end
        days = map2(b, e, ~ seq.Date(.x, .y, by = "1 day"))) |>
  # unnest the days column into many rows
  unnest(days) |>
  # if the beginning date is the same as the date in `days`, then use the original Begin column
  # else, use `days` as a datetime
  mutate(Begin = if_else(b == days, Begin, as_datetime(days)),
         # same with End, but subtracting one minute
         End = if_else(e == days, End, as_datetime(days) + days(1) - seconds(1)), .keep = "unused")

输出:

  Group Begin               End                
  <chr> <dttm>              <dttm>             
1 A     2023-07-15 01:40:11 2023-07-15 13:43:15
2 B     2023-07-22 05:54:44 2023-07-24 23:59:00
3 B     2023-07-22 00:00:00 2023-07-24 23:59:00
4 B     2023-07-22 00:00:00 2023-07-24 23:59:00
5 B     2023-07-22 00:00:00 2023-07-25 10:50:45
6 C     2023-08-05 16:43:09 2023-08-05 23:59:00
7 C     2023-08-05 00:00:00 2023-08-06 10:42:12

R相关问答推荐

如何将图案添加到ggplot中的一个类别

强制相关图以显示相关矩阵图中的尾随零

变量计算按R中的行更改

管道末端运行功能

咕噜中的元素列表:map

如何写一个R函数来旋转最后n分钟?

如何改变时间图R中的悬停信息?

使用geom_segment()对y轴排序

移除仪表板Quarto中顶盖和车身之间的白色区域

`lazy_dt`不支持`dplyr/across`?

SHINY:使用JS函数应用的CSS样式显示HTML表格

过滤名称以特定字符串开头的文件

R -在先前group_by级别汇总时获取最大大小子组的计数

基于数据集属性将科分配给物种

有没有可能用shiny 的书签恢复手风琴面板?

在纵向数据集中创建新行

将摘要图添加到facet_WRAP gglot的末尾

如何阻止围堵地理密度图?

长/纬点继续在堪萨斯-SF结束,整齐的人口普查

我已经运行了几个月的代码的`Palette()`中出现了新的gglot错误