使用R计算每个通断事件周期内的时间间隔
问题描述
现有数据集如下:
data<-data.frame(time=c(20230404001040, 20230404001050,20230404001100, 20230404001110, 20230404001120,20230404001130, 20230404001140,20230404001150,20230404001200), on=c("FALSE", "FALSE", "FALSE", "TRUE","TRUE","TRUE","FALSE","FALSE","FALSE"))
其中time列可通过data[,1] <- ymd_hms(data[,1])转换为ymd_hms格式;on列中FALSE代表开关断开,TRUE代表开关闭合。
需求是计算每个通断事件的持续时长,每行时间间隔为10秒,需生成time_after_switch列,期望输出如下:
data<-data.frame(time=c(20230404001040, 20230404001050,20230404001100, 20230404001110, 20230404001120,20230404001130, 20230404001140,20230404001150,20230404001200), on=c("FALSE", "FALSE", "FALSE", "TRUE","TRUE","TRUE","FALSE","FALSE","FALSE"), time_after_switch=c(0,10,20,0,10,20,0,10,20))
数据集前3行是开关断开事件,中间3行是闭合事件,最后3行是断开事件,共3个周期。求实现该需求的R代码。
解决方案
方法一:使用dplyr包(推荐)
借助分组计算识别连续通断事件,再按组生成递增时长:
library(dplyr) library(lubridate) # 加载原始数据 data <- data.frame( time = c(20230404001040, 20230404001050, 20230404001100, 20230404001110, 20230404001120, 20230404001130, 20230404001140, 20230404001150, 20230404001200), on = c("FALSE", "FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", "FALSE") ) # 转换time列为时间格式 data$time <- ymd_hms(data$time) # 生成目标列 data <- data %>% # 创建事件组标识:on值变化时组号递增 mutate(group = cumsum(on != lag(on, default = first(on)))) %>% # 按组计算从0开始的10秒递增时长 group_by(group) %>% mutate(time_after_switch = (row_number() - 1) * 10) %>% ungroup() %>% # 移除临时组列(可选) select(-group)
方法二:基础R实现
无需额外包,通过序列分组计算:
library(lubridate) # 加载并转换时间格式 data <- data.frame( time = c(20230404001040, 20230404001050, 20230404001100, 20230404001110, 20230404001120, 20230404001130, 20230404001140, 20230404001150, 20230404001200), on = c("FALSE", "FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", "FALSE") ) data$time <- ymd_hms(data$time) # 创建事件组 group <- c(1, cumsum(data$on[-1] != data$on[-nrow(data)]) + 1) # 计算time_after_switch列 data$time_after_switch <- unlist(lapply(split(seq_along(group), group), function(x) (x - min(x)) * 10))
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

