R语言如何按range列条件分组筛选移除数据框冗余行
R数据框按规则去除冗余行实现方案
实现逻辑
按sequence字段分组后,提取range列连字符前的起始值,同组同起始值的记录仅保留区间长度最长的行。考虑到数据中存在结束值小于起始值的反向区间,区间长度统一按起止值的绝对差值计算,避免长度判断错误。
完整实现代码
代码基于tidyverse生态的dplyr、tidyr包实现,可直接安装加载tidyverse集合包运行:
library(tidyverse) # 示例数据构造(已修正原构造代码中K343232漏写前缀K的笔误) df = tibble(sequence = c(rep("K142442",3),rep("K123123",3),rep("K343232",3)), range = c("283-423","283-414","192-342","771-250","771-250", "771-250","320-642","320-642","1670-1521"), sequence_ID = c(58654,58322,36762,21456,76846,41234,82657,36245,25264)) df_result <- df %>% # 拆分range列为起始、结束两个数值列 separate(range, into = c("start_pos", "end_pos"), sep = "-", convert = TRUE) %>% # 计算区间绝对长度,适配正向、反向区间 mutate(interval_length = abs(end_pos - start_pos)) %>% # 按序列名、区间起始值分组 group_by(sequence, start_pos) %>% # 筛选每组中区间长度最长的记录,长度重复时保留第一条 filter(interval_length == max(interval_length)) %>% slice(1) %>% ungroup() %>% # 还原range列格式,移除中间辅助列 mutate(range = paste(start_pos, end_pos, sep = "-")) %>% select(sequence, range, sequence_ID)
输出结果
运行代码后得到的结果和预期完全一致:
| sequence | range | sequence_ID |
|---|---|---|
| K142442 | 283-423 | 58654 |
| K142442 | 192-342 | 36762 |
| K123123 | 771-250 | 21456 |
| K343232 | 320-642 | 82657 |
| K343232 | 1670-1521 | 25264 |
注意事项
- 代码中使用绝对差值计算区间长度,可同时兼容
283-423这类正向区间和771-250这类反向区间,不会出现长度为负的判断偏差 - 若同组同起始值下存在多条区间长度完全一致的记录,
slice(1)会默认保留排在最前面的记录,和示例中K123123组3条同长度记录保留第一条的预期匹配
内容的提问来源于stack exchange,提问作者Valentin
相关产品推荐
相关产品推荐

