R语言中多日期时间组合下连续时间事件的时长求和方法
实现逻辑
原有方案未按date.1字段分组计算、未处理跨日期的时间序列边界,导致时间差计算不符合预期。以下方案先合并日期与时间为完整时间戳,按日期分组后识别间隔不超过1秒的连续观测段,再按段统计总时长。
Tidyverse 实现(推荐)
依赖dplyr和lubridate包,代码简洁易读:
# 加载依赖 library(dplyr) library(lubridate) # 示例数据 date.1 <- c("2021-07-21", "2021-07-21", "2021-07-21", "2021-07-29", "2021-07-29", "2021-07-30", "2021-08-01","2021-08-01","2021-08-01") time.1 <- c("15:57:59", "15:58:00", "15:58:01", "15:46:10", "15:46:13", "18:12:10", "18:12:10","18:12:11","18:12:13") df <- data.frame(date.1, time.1) # 统计计算 result <- df %>% # 合并为完整时间戳 mutate(datetime = ymd_hms(paste(date.1, time.1), tz = "UTC")) %>% # 按日期分组处理 group_by(date.1) %>% # 标记连续段:首行/间隔大于1秒则开启新段 mutate(seg_id = cumsum(c(TRUE, diff(datetime) > 1))) %>% # 按日期+连续段聚合统计 group_by(date.1, seg_id) %>% summarise( time.1 = first(time.1), # 总时长=最后时间-开始时间+1(统计观测点覆盖的总秒数) secs = as.integer(last(datetime) - first(datetime)) + 1, .groups = "drop" ) %>% select(-seg_id)
输出结果与预期完全一致:
# A tibble: 6 × 3 date.1 time.1 secs <chr> <chr> <dbl> 1 2021-07-21 15:57:59 3 2 2021-07-29 15:46:10 1 3 2021-07-29 15:46:13 1 4 2021-07-30 18:12:10 1 5 2021-08-01 18:12:10 2 6 2021-08-01 18:12:13 1
基础R实现(无需第三方包)
如果不想安装额外包,可以用基础R函数实现:
# 构造完整时间戳 df$datetime <- as.POSIXct(paste(df$date.1, df$time.1), tz = "UTC") # 按日期拆分数据 df_split <- split(df, df$date.1) # 逐日期统计连续段 result <- do.call(rbind, lapply(df_split, function(sub_df) { # 按时间排序 sub_df <- sub_df[order(sub_df$datetime), ] # 标记连续段id sub_df$seg_id <- cumsum(c(TRUE, diff(sub_df$datetime) > 1)) # 逐段统计时长 do.call(rbind, lapply(split(sub_df, sub_df$seg_id), function(seg) { data.frame( date.1 = seg$date.1[1], time.1 = seg$time.1[1], secs = as.integer(difftime(seg$datetime[nrow(seg)], seg$datetime[1], units = "secs")) + 1 ) })) })) # 重置行号 rownames(result) <- NULL
内容的提问来源于stack exchange,提问作者hylaeus
相关产品推荐
相关产品推荐

