如何在R DataFrame中基于多条件重置计算间隔流逝时间列
解决方案:计算R数据框中自上次断点后的流逝时间
完整实现代码
library(dplyr) # 原始数据框 df1 <- data.frame(p1 = c("John", "John", "John", "John", "John", "John", "Jim", "Jim", "Jim", "Jim", "Jim", "Jim", "Jim","Jim" ), elapsed_time = c(0, 4, 6, 9, 12, 14, 17, 22, 27, 35, 42, 47, 51, 57), event_type = c("start of period", "play", "play", "play", "play", "play", "play", "play", "play", "timeout", "play", "play", "play", "play")) # 计算目标列 df1 <- df1 %>% # 标记所有需要重置时间的断点行 mutate(is_break = case_when( event_type %in% c("start of period", "timeout") ~ TRUE, p1 != lag(p1, default = first(p1)) ~ TRUE, TRUE ~ FALSE )) %>% # 生成断点分组ID:每遇到一个断点就开启新分组 mutate(break_group = cumsum(is_break)) %>% # 按分组计算自组内起始时间的差值 group_by(break_group) %>% mutate(elapsed_time_since_last_break = elapsed_time - first(elapsed_time)) %>% # 移除辅助列(可选) ungroup() %>% select(-is_break, -break_group) # 查看结果 print(df1)
步骤解释
标记断点行:
用case_when创建is_break列,满足以下任一条件则标记为TRUE:- 事件类型是
start of period或timeout - 当前行的
p1与上一行不同(lag函数获取上一行值,default参数处理第一行无前置行的情况)
- 事件类型是
生成分组ID:
通过cumsum(is_break)累加断点标记,每遇到一个断点,分组ID自动加1,确保同一个连续区间的行被分到同一组。计算自断点后的时间:
按break_group分组,用当前行的elapsed_time减去组内第一行的elapsed_time,得到自上次断点后的流逝时间,断点行的结果自然为0。清理辅助列:
用ungroup取消分组,再移除is_break和break_group两个辅助列,得到最终结果。
输出结果
运行代码后会得到你期望的输出:
p1 elapsed_time event_type elapsed_time_since_last_break 1 John 0 start of period 0 2 John 4 play 4 3 John 6 play 6 4 John 9 play 9 5 John 12 play 12 6 John 14 play 14 7 Jim 17 play 0 8 Jim 22 play 5 9 Jim 27 play 10 10 Jim 35 timeout 0 11 Jim 42 play 7 12 Jim 47 play 12 13 Jim 51 play 16 14 Jim 57 play 22
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

