我有两个id的对列表:(ida,idb)。 我想从这个列表中构建一个“唯一对”列表,意思是每个id(ida和idb)只使用一次。
ida的某些元素可能与idb的任何元素都不匹配。但是必须保留idb的所有元素(如下例中的第6行和第6行)。
这意味着解决方案的最终对的数量应该等于idb的唯一元素的数量。
有时可能有多种解决方案,我只需要其中一种。
dt1 = data.table(ida = c(7,7,8,8,15,16,17,18,19,19,20), idb = c(2,1,2,1,4,5,5,6,7,8,8))
ida idb
1: 7 2
2: 7 1
3: 8 2
4: 8 1
5: 15 4
6: 16 5
7: 17 5
8: 18 6
9: 19 7
10: 19 8
11: 20 8
收率:
ida idb
1: 7 2
2: 8 1
3: 15 4
4: 16 5
5: 18 6
6: 19 7
7: 20 8
或者:
ida idb
1: 7 1
2: 8 2
3: 15 4
4: 17 5
5: 18 6
6: 19 7
7: 20 8
我们有nrow(result)== length(unique(dt1 $ idb))。当然长度(唯一(结果$ ida))== length(唯一(结果$ idb))。
注意:在第一个解决方案中,元素17已从ida中删除。这是一种预期的行为:不可能同时将16和17链接到5,因为5必须是唯一的。
答案 0 :(得分:0)
我是以自己的方式做到的,这有点慢,但有效:
my_rows = NULL
sets = dt[, .(ida, idb)]
my_rows = sets[!duplicated(idb) & !duplicated(idb, fromLast = TRUE)]
sets = sets[!ida %in% my_rows$ida]
setkey(sets, idb)
for (idb in unique(sets$idb)) {
elem = sets[J(idb)]
my_rows = rbind(my_rows, elem[1])
sets = sets[ida != elem$ida[1]]
}
随意张贴更短的&如果你有更快的答案!