R语言分组后检测区间是否重叠的实现问题
按染色体分组检测区间重叠的正确实现方法
需求明确:按chr列分组,对每行的range2(start2, end2),判断其是否与同组内任意range1(start1, end1)存在重叠,新增OVERLAP列标记结果。针对你用ivs包出现全TRUE的错误结果,以下是两种可靠解决方案:
示例数据与期望输出
先明确示例数据df1的期望结果:
OVERLAP列应为TRUE, TRUE, FALSE, FALSE
- chr1组的两个range2均与组内的(200,400)range1重叠
- chr2组的两个range2与组内所有range1无重叠
library(dplyr) df1 <- tibble(chr=c(1,1,2,2), start1=c(100,200,100,200), end1=c(150,400,150,400), species=c("Penguin"), start2=c(200,200,500,1000), end2=c(250,240,1000,2000) )
方法1:使用ivs包正确实现
之前的错误核心是未按分组聚合所有range1,而是错误地逐行配对比较。正确做法是先将同组所有range1打包成区间向量,再检查每行range2是否与该向量中任意区间重叠:
library(ivs) df_result <- df1 %>% group_by(chr) %>% mutate( # 构建同组所有range1的区间集合 all_range1 = list(iv(start1, end1)), # 检查当前行range2是否与集合中任意区间重叠 OVERLAP = iv_overlaps(iv(start2, end2), all_range1[[1]]) ) %>% ungroup() %>% select(-all_range1) # 移除临时辅助列 print(df_result)
方法2:不依赖ivs包,用基础逻辑实现
如果不想引入额外包,可直接用区间重叠的核心判断规则:两个区间(a1,a2)和(b1,b2)重叠的条件是a1 < b2 & b1 < a2,按分组批量检查即可:
df_result <- df1 %>% group_by(chr) %>% mutate( # 收集同组所有range1的起始/结束值 range1_starts = list(start1), range1_ends = list(end1), # 逐行判断当前range2是否与任意range1重叠 OVERLAP = pmap_lgl(list(start2, end2), function(s2, e2) { any(s2 < range1_ends[[1]] & range1_starts[[1]] < e2) }) ) %>% ungroup() %>% select(-range1_starts, -range1_ends) # 移除临时辅助列 print(df_result)
错误原因说明
你之前得到全TRUE的结果,大概率是错误地直接逐行比较当前行的range1和range2(比如写了iv_overlaps(iv(start1, end1), iv(start2, end2))),而非检查同组内所有range1,完全偏离了需求逻辑。
内容的提问来源于stack exchange,提问作者LDT
相关产品推荐
相关产品推荐

