我试图通过查找另一个 ID (ID2) 来链接两组匿名 ID(ID1 和 ID3)。我只想保留 ID1 和 ID3 之间的一对一匹配,但这很棘手,因为每个 ID 之间存在多对多匹配。
library(data.table)
Table1 <- data.table(ID1 = c(1, 1, 2, 3, 4, 5, 5, 6),
ID2 = c(101, 102, 102, 103, 104, 105, 106, 107))
Table2 <- data.table(ID2 = c(101, 102, 103, 103, 104, 105, 106, 108),
ID3 = c(201, 202, 203, 204, 205, 206, 206, 207))
我尝试过加入桌子。这成功地消除了 ID2 仅出现在其中一张表中的情况。
setkey(Table1,ID2)
setkey(Table2,ID2)
merged_table <- Table2[Table1,nomatch=0]
但是,它仍然包含 ID1 链接到多个 ID3 值的情况,反之亦然。
我想最终得到一个像这样的桌子:
ID1 ID3
4 205
5 206
理想情况下,我想在 R 中使用
data.table
来完成此操作。
我想更简单的方法可能是同时使用
data.table
和 igraph
,例如,
library(igraph)
library(data.table)
d <- unique(Table1[Table2, .(ID1, ID3), on = .(ID2), nomatch = 0])
d %>%
graph_from_data_frame() %>%
decompose() %>%
Filter(\(x) vcount(x) == 2, .) %>%
{
d[ID1 %in% sapply(., \(x) names(V(x)))]
}
这给出了
ID1 ID3
1: 4 205
2: 5 206
我已经找到了一种方法来回答我自己的问题,使用
data.table
:
# Do a full join of the two tables
setkey(Table1, ID2)
setkey(Table2, ID2)
combined_lookups <- Table2[Table1,nomatch=0]
# Count the number of matches in both directions
combined_lookups[, count1 := uniqueN(ID1), by = ID3]
combined_lookups[, count2 := uniqueN(ID3), by = ID1]
# Then remove cases where ID's match multiple person_ids, and vice versa. Also remove duplicate rows.
final_table <- unique(combined_lookups[count1==1 & count2==1][,.(ID1,ID3)])
但是,实际的表非常大,创建
count1
和 count2
列非常慢。如果有人能提出更有效的解决方案,我仍然会很感激。