R语言data.table自交叉连接 排除对称重复及等值结果
data.table 生成无重复无序id对的高效实现
需求说明
现有data.table表init,结构如下:
> init id 1: a 2: b 3: c
需要对id列做自连接生成所有值对,满足:
- 排除两个值相等的配对
- 排除对称重复配对(如
(a,b)和(b,a)仅保留1条) - 适配大体量数据集,执行效率优先
期望输出结果:
id1 id2 1: a b 2: a c 3: b c
方案1:直接生成目标结果(最高效,推荐大体量数据使用)
不要先生成全量交叉连接再过滤——全量交叉连接会生成n²行冗余数据,id基数大时内存占用极高。直接生成所有无序两两组合即可,全程无冗余计算:
library(data.table) # 示例数据初始化 init <- data.table(id = c("a", "b", "c")) # 生成所有无重复无序对 result <- as.data.table(t(combn(init$id, 2))) setnames(result, c("id1", "id2"))
该方案最终仅生成需要的n*(n-1)/2行结果,内存占用和计算量都是最小的,适配百万级以上id的场景。
方案2:过滤已生成的全量交叉连接结果
如果你已经通过CJ(init$id, init$id)生成了全量交叉表full_cj,仅需一行向量式过滤即可得到目标结果,不需要额外去重:
# 已生成的全量交叉连接 full_cj <- CJ(init$id, init$id) # 单次过滤移除同值、对称重复行 result <- full_cj[V1 < V2, .(id1 = V1, id2 = V2)]
- 过滤逻辑:
V1 < V2判断会直接排除V1 == V2的同值配对- 任意对称配对
(x,y)和(y,x)中,仅排序更小的值在前的行会被保留,自动去除对称重复 - 该过滤是data.table原生向量操作,无行级循环,执行效率极高
- 注意:该方案依赖前置生成的
n²行全量表,id基数超过10万时内存压力会非常大,优先选择方案1。
内容的提问来源于stack exchange,提问作者red_quark
相关产品推荐
相关产品推荐

