You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于两列数值范围对大文件数据聚类并保留簇首行?

基于数值范围连续性的data.table聚类处理

问题描述

我有一个大型data.table格式的文件,需要基于start和end列的数值范围进行聚类:当某一行的start值等于前一行的end值+1时,两行属于同一聚类;间隔较大则分为不同聚类。最终每个聚类仅保留第一行数据。

示例输入

df <- setDT(data.frame(name = c("chr1", "chr1", "chr1", "chr1","chr1","chr1"), 
  start = c(8480001, 8480251, 10006251, 10006501,13910501,14841751), 
  end = c(8480250, 8480500, 10006500, 10006750,13910750,14842000),
  length = c(250, 250, 250, 250,250,250))) 

期望输出

output <- setDT(data.frame(name = c("chr1", "chr1", "chr1", "chr1"),
  start = c(8480001, 10006251, 13910501, 14841751), 
  end = c(8480250, 10006500, 13910750, 14842000), 
  length = c(250, 250, 250, 250))) 

解决方案

针对大型数据集,使用data.table的内置操作可高效完成需求,步骤如下:

  1. 排序数据:确保数据按分组列(如name)和start列排序,保证区间顺序正确:
setorder(df, name, start)
  1. 生成聚类标识:通过判断当前行start与前一行end的连续性,生成聚类分组ID:
df[, cluster := cumsum(start != shift(end, fill = start[1] - 2) + 1), by = name]
  • shift(end, fill = start[1]-2)为第一行设置一个不会触发连续判断的初始值,确保第一个聚类从ID 1开始
  • cumsum会在每次遇到不连续区间时递增聚类ID,实现自动分组
  1. 提取每组首行:按聚类ID分组,保留每组的第一行数据:
output <- df[, .SD[1], by = cluster]
# 可选:移除聚类ID列
output[, cluster := NULL]

验证结果

运行上述代码后,打印output即可得到与期望一致的结果:

print(output)

关键说明

  • 按name分组处理:避免不同染色体(或其他分组)的区间被错误合并
  • 高效性:data.table的操作均为内存内向量运算,适合处理百万级以上的大型数据集,性能远高于循环或其他低效方法

内容的提问来源于stack exchange,提问作者mehdi heidari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:18:21