R语言:按id与gr分组筛选满足位置A→B→A序列的分组数据框行
位置往返模式识别实现方案
核心逻辑
- 严格以
id+gr作为分组唯一键,避免跨组序列混算 - 对每个分组的位置序列做连续同值压缩:把连续停留的重复位置合并为单节点,剔除无移动的无效占位,得到只包含位置变化的精简序列
- 在精简序列中识别标准的
A→B→A模式:连续三个位置节点满足「首节点≠中间节点,中间节点≠尾节点,首节点=尾节点」 - 提取所有命中规则的(id, gr)组合作为输出
可直接运行的完整代码
library(dplyr) # 示例数据集 df <- data.frame( id = c(1,1,1,1,1,1,1,2,2,2,2,2,4,4,4,4,4,4,4,4), gr = c(1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4), loc = c(5,5,4,4,5,5,5,3,3,3,3,2,2,2,2,3,3,2,2,2) ) # 模式识别流程 out <- df %>% group_by(id, gr) %>% # 压缩连续重复的同位置 mutate( loc_seq = case_when( row_number() == 1 ~ loc, loc == lag(loc) ~ NA_integer_, T ~ loc ) ) %>% filter(!is.na(loc_seq)) %>% # 检查是否存在A→B→A的连续模式 summarise( is_match = any( loc_seq != lead(loc_seq) & lead(loc_seq) != lead(loc_seq, n = 2) & loc_seq == lead(loc_seq, n = 2), na.rm = T ) ) %>% filter(is_match) %>% select(id, gr)
运行结果
执行上述代码后得到的输出与期望完全一致:
> out # A tibble: 2 × 2 id gr <dbl> <dbl> 1 1 1 2 4 4
之前方案失效的原因说明
- 直接使用全局
diff计算位置差,未绑定分组维度,会把跨组的位置序列拼接计算,出现逻辑错误 - 未做连续同值压缩时,连续停留的重复位置会被当成独立节点,导致位置差序列出现大量0值,无法有效定位真实移动节点
- 单按
id分组不符合业务规则:同一id在不同gr下是完全独立的观测序列,必须双维度分组才能保证序列边界正确
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

