如何按午夜分割DataFrame时间行?求tidyverse解决方案
按午夜分割跨天事件的tidyverse解决方案
问题描述
现有如下格式的DataFrame:
event start.time end.time connected 04.08.21 20:48 04.08.21 20:59 disconnected 04.08.21 20:59 06.08.21 14:29
需要将跨天的事件按午夜分割,把一个跨多天的事件拆分为多个单日片段,最终得到如下结果:
event start.time end.time connected 04.08.21 20:48 04.08.21 20:59 disconnected 04.08.21 20:59 04.08.21 23:59 disconnected 05.08.21 00:00 05.08.21 23:59 disconnected 06.08.21 00:00 06.08.21 14:29
可复现代码:
data <- data.frame( event = c("connected", "disconnected"), start.time = c("04.08.21 20:48", "04.08.21 20:59"), end.time = c("04.08.21 20:59", "06.08.21 14:29") )
解决方案
使用tidyverse生态中的dplyr、tidyr和lubridate包实现,步骤如下:
- 加载所需包
library(tidyverse) library(lubridate)
- 转换时间格式并生成事件覆盖的日期序列
data_processed <- data %>% # 将字符串时间转为datetime对象,匹配日.月.年 时分的格式 mutate( start_datetime = dmy_hm(start.time), end_datetime = dmy_hm(end.time) ) %>% # 按行生成事件覆盖的所有日期 rowwise() %>% mutate(date_sequence = list(seq.Date(date(start_datetime), date(end_datetime), by = "day"))) %>% unnest(date_sequence)
- 计算每个日期片段的起止时间并格式化
data_split <- data_processed %>% mutate( # 确定片段开始时间:起始日期用原事件开始时间,其他日期用当天0点 segment_start = if_else(date_sequence == date(start_datetime), start_datetime, ymd_hms(paste(date_sequence, "00:00:00"))), # 确定片段结束时间:结束日期用原事件结束时间,其他日期用当天23:59:59(近似23:59) segment_end = if_else(date_sequence == date(end_datetime), end_datetime, ymd_hms(paste(date_sequence, "23:59:59"))) ) %>% # 转换回原始字符串格式 mutate( start.time = format(segment_start, "%d.%m.%y %H:%M"), end.time = format(segment_end, "%d.%m.%y %H:%M") ) %>% # 保留目标列 select(event, start.time, end.time)
- 查看最终结果
print(data_split)
输出结果:
# A tibble: 4 × 3 event start.time end.time <chr> <chr> <chr> 1 connected 04.08.21 20:48 04.08.21 20:59 2 disconnected 04.08.21 20:59 04.08.21 23:59 3 disconnected 05.08.21 00:00 05.08.21 23:59 4 disconnected 06.08.21 00:00 06.08.21 14:29
内容的提问来源于stack exchange,提问作者diggi2395
相关产品推荐
相关产品推荐

