如何用gsub筛选HH:MM-HH:MM时段并排除@HH:MM格式事件时间?
解决方案
1. 保留为逗号分隔的清理后字符串
要提取HH:MM-HH:MM格式的时段并清理无效内容,通过两次正则替换即可实现:
# 原始数据 id <- c("3990", "3989", "3004") timepoints <- c("@6:19,,7:16-7:23,7:25-7:43,@7:53,", "@6:19,,7:25-7:43,@7:53", "7:30-7:39,7:45-7:48,7:49-7:54") df <- data.frame(id, timepoints) # 清理步骤 df$cleaned_time <- gsub("@\\d+:\\d+", "", df$timepoints) # 移除所有@HH:MM格式的内容 df$cleaned_time <- gsub(",+", ",", df$cleaned_time) # 将连续逗号替换为单个逗号 df$cleaned_time <- gsub("^,|,$", "", df$cleaned_time) # 移除开头/结尾的逗号 df$cleaned_time <- gsub(",", ", ", df$cleaned_time) # 可选:给逗号后加空格优化格式
执行后得到的结果:
| id | cleaned_time |
|---|---|
| 3990 | 7:16-7:23, 7:25-7:43 |
| 3989 | 7:25-7:43 |
| 3004 | 7:30-7:39, 7:45-7:48, 7:49-7:54 |
2. 拆分为长格式方便计算时长
如果需要进一步计算每个暂停时段的时长并从总时长中扣除,可以将数据转换为包含开始/结束时间的长格式:
library(tidyr) library(dplyr) library(lubridate) df_processed <- df %>% # 先清理原始字符串 mutate(cleaned_time = gsub("@\\d+:\\d+", "", timepoints)) %>% mutate(cleaned_time = gsub(",+", ",", cleaned_time)) %>% mutate(cleaned_time = gsub("^,|,$", "", cleaned_time)) %>% # 将每个时段拆分为单独行 separate_rows(cleaned_time, sep = ",") %>% filter(cleaned_time != "") %>% # 拆分开始和结束时间 separate(cleaned_time, into = c("start", "end"), sep = "-") %>% # 转换为时间格式并计算时长(单位:分钟) mutate( start = hm(start), end = hm(end), pause_duration = as.duration(end - start) / dminutes(1) )
最终的df_processed会包含每个id对应的所有暂停时段的开始、结束时间及时长,直接求和pause_duration即可得到总暂停时长,再从总观测时长中扣除。
正则表达式说明
@\\d+:\\d+:匹配完整的@HH:MM格式,确保一次性移除整个标记事件的时间,+:匹配连续的逗号(比如原始数据中的,,),替换为单个逗号避免空值^,|,$:匹配字符串开头或结尾的逗号,清理无效的首尾分隔符
内容的提问来源于stack exchange,提问作者Anka
相关产品推荐
相关产品推荐

