如何在R中按重叠范围列对DataFrame行进行分组?
为重叠基因组区间的行分配分组编号
原始数据
首先给出你的DataFrame:
data <- data.frame( chr = c(11, 11, 11, 11, 11, 11), start = c(2530025, 431647, 1241413, 2891739, 4121824, 2324189), end = c(2641128, 944232, 2446722, 2933803, 6426100, 3873886), BP = c(2530025, 707496, 2159979, 2933803, 5226820, 3518621), A1FREQ = c(0.001469300, 0.000689781, 0.000848240, 0.001410370, 0.004475170, 0.001768870), N = c(22397, 22397, 22397, 22753, 22753, 22753), SE = c(0.1363820, 0.1857480, 0.1685630, 0.1264720, 0.0739399, 0.1115480), p = c(4.346403e-08, 9.899198e-11, 4.843954e-19, 2.158341e-09, 8.063062e-78, 1.348031e-27) )
需求说明
新增一列group,为存在重叠的start和end基因组区间的行分配相同的分组编号。
实现方法
方法一:Base R 原生实现
通过排序后遍历判断区间重叠,手动分配分组:
# 按start列排序,方便判断重叠 data_sorted <- data[order(data$start), ] # 初始化分组列和当前组的最大end值 data_sorted$group <- 1 current_max_end <- data_sorted$end[1] # 遍历后续行,判断是否与当前组重叠 for (i in 2:nrow(data_sorted)) { if (data_sorted$start[i] <= current_max_end) { # 区间重叠,归为同一组,更新当前组的最大end current_max_end <- max(current_max_end, data_sorted$end[i]) } else { # 区间不重叠,创建新分组 data_sorted$group[i] <- data_sorted$group[i-1] + 1 current_max_end <- data_sorted$end[i] } } # 将分组结果映射回原数据框(保留原始行顺序) data$group <- data_sorted$group[match(rownames(data), rownames(data_sorted))]
方法二:使用IRanges包(更高效)
IRanges是Bioconductor专门处理区间操作的包,适合处理大规模数据集:
# 安装包(首次使用需执行) # install.packages("BiocManager") # BiocManager::install("IRanges") # 加载包 library(IRanges) # 创建IRanges对象 ir_obj <- IRanges(start = data$start, end = data$end) # 合并重叠区间,然后匹配每个原始区间所属的合并组 merged_ir <- reduce(ir_obj) group_ids <- findOverlaps(ir_obj, merged_ir, type = "within") %>% as.data.frame() %>% pull(subjectHits) # 为原数据框添加分组列 data$group <- group_ids
结果验证
执行后查看分组结果:
print(data[, c("start", "end", "group")])
输出示例:
start end group 1 2530025 2641128 2 2 431647 944232 1 3 1241413 2446722 2 4 2891739 2933803 3 5 4121824 6426100 4 6 2324189 3873886 2
可以看到第1、3、6行的区间相互重叠,被分配到同一分组(编号2),其余不重叠区间各为独立分组。
内容的提问来源于stack exchange,提问作者Khaleesi95
相关产品推荐
相关产品推荐

