使用data.table R从多对多链接中获取一对一匹配

问题描述 投票:0回答:2

我试图通过查找另一个 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
来完成此操作。

r data.table outer-join
2个回答
0
投票

我想更简单的方法可能是同时使用

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

0
投票

我已经找到了一种方法来回答我自己的问题,使用

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
列非常慢。如果有人能提出更有效的解决方案,我仍然会很感激。

© www.soinside.com 2019 - 2024. All rights reserved.