在R中按参与者ID清理时间序列:移除非连续Beep行
多参与者ESM时间序列数据清理方案
核心思路
通过按参与者ID+天分组,在组内判断当前Beep与前后记录的间隔,仅保留同一天内Beep间隔为1的连续行,彻底避免跨天误删。
实现代码(R + dplyr)
假设你的数据框名为df,包含ID(参与者ID)、Day(天数)、Beep(提醒次数)及其他变量:
library(dplyr) # 清理数据:保留同一天内Beep连续间隔1的行 cleaned_df <- df %>% # 按参与者+天分组,确保仅在同一天内处理 group_by(ID, Day) %>% # 计算当前Beep与前/后Beep的间隔 mutate( prev_beep_gap = Beep - lag(Beep, default = NA), next_beep_gap = lead(Beep, default = NA) - Beep ) %>% # 过滤条件:与前一个或后一个Beep间隔为1的行 # 孤立的Beep(无相邻间隔1的记录)会被自动剔除 filter((prev_beep_gap == 1) | (next_beep_gap == 1)) %>% # 删除临时计算的辅助列 select(-prev_beep_gap, -next_beep_gap) %>% # 取消分组 ungroup()
备选方案(基于你创建的day_beep变量)
如果你想直接使用已有的day_beep(Day×10+Beep),逻辑完全一致,仅需替换判断变量:
cleaned_df <- df %>% group_by(ID, Day) %>% mutate( prev_db_gap = day_beep - lag(day_beep, default = NA), next_db_gap = lead(day_beep, default = NA) - day_beep ) %>% filter((prev_db_gap == 1) | (next_db_gap == 1)) %>% select(-prev_db_gap, -next_db_gap) %>% ungroup()
效果说明
- 同一参与者同一天内,连续的Beep(如1→2→3)会被完整保留;
- 同一Day内孤立的Beep(如单独的Beep4,或Beep1→3)会被剔除;
- 跨天的记录(如Day2 Beep1与Day1 Beep7)因分组隔离,不会被误删。
内容的提问来源于stack exchange,提问作者Snight
相关产品推荐
相关产品推荐

