基于连续零长度条件移除R数据框按id分组的var1列末尾连续零
实现思路
- 按id字段对数据框分组处理
- 对每组的var1序列,通过游程编码(RLE)统计两类指标:全组所有连续0序列的最大长度、末尾连续0的长度
- 若末尾连续0长度≥全组最大连续0长度,则截断末尾的连续0,否则保留原组全部数据
代码实现
方法1:dplyr + 自定义处理函数
library(dplyr) # 定义单组序列处理函数 trim_tail_zeros <- function(x) { rle_x <- rle(x) # 无0的情况直接返回原序列 zero_runs <- rle_x$lengths[rle_x$values == 0] if (length(zero_runs) == 0) return(x) max_zero_len <- max(zero_runs) # 末尾不是0直接返回 if (tail(rle_x$values, 1) != 0) return(x) tail_zero_len <- tail(rle_x$lengths, 1) # 符合截断条件则删除末尾连续0 if (tail_zero_len >= max_zero_len) { keep_n <- sum(head(rle_x$lengths, -1)) return(x[1:keep_n]) } else { return(x) } } # 分组处理数据 df_result <- df %>% group_by(id) %>% filter(seq_along(var1) <= length(trim_tail_zeros(var1))) %>% ungroup()
方法2:base R 实现(无需额外包)
df_result <- do.call(rbind, lapply(split(df, df$id), function(sub_df) { x <- sub_df$var1 rle_x <- rle(x) zero_runs <- rle_x$lengths[rle_x$values == 0] if (length(zero_runs) == 0) return(sub_df) max_zero_len <- max(zero_runs) if (tail(rle_x$values,1) !=0 ) return(sub_df) tail_zero_len <- tail(rle_x$lengths,1) if (tail_zero_len >= max_zero_len) { keep_n <- sum(head(rle_x$lengths, -1)) return(sub_df[1:keep_n, ]) } else { return(sub_df) } })) rownames(df_result) <- NULL
效果验证
- 对示例中的id=a分组,处理后仅保留前12行,末尾8个连续0被删除
- 对示例中的id=b分组,末尾2个连续0小于最大连续0长度(10),因此20行数据全部保留
内容的提问来源于stack exchange,提问作者procerus
相关产品推荐
相关产品推荐

