使用 data.table 过滤以仅保留一对一匹配
Filter to keep only one-to-one matches using data.table
我正在使用包含两个 ID 列的大型 table。例如
ID1 ID2
01A XY1
01B XY4
...
两个 ID 列中都有重复的值,并且已决定仅保留两个 ID 之间存在一对一匹配的情况。即,如果任何 ID1 值与多个 ID2 值匹配,则删除具有该 ID1 值的所有行。反之亦然。
我使用 dplyr
编写了一些有效的代码:
df %>%
group_by(ID1) %>%
filter(n_distinct(ID2)==1) %>%
distinct() %>%
filter(!is.na(ID2)) %>%
group_by(ID2) %>%
filter(n_distinct(ID1)==1) %>%
distinct() %>%
filter(!is.na(ID1))
但是,由于 table 的大小,这对 运行 来说相当慢。我正在尝试弄清楚如何使用 data.table
来做同样的事情。我认为它必须使用 unique
和 uniqueN
的某种组合,但似乎不太正确。
非常感谢任何帮助。
在data.table
中,你可以做-
library(data.table)
setDT(df)
na.omit(unique(df[, .SD[uniqueN(ID2) == 1], ID1][,
.SD[uniqueN(ID1) == 1], ID2]))
我们可以做到
library(data.table)
tmp <- setDT(df)[df[, .I[uniqueN(ID2)== 1], ID1]$V1]
na.omit(unique(tmp[tmp[, .I[uniqueN(ID1) == 1], ID2]$V1]))
我正在使用包含两个 ID 列的大型 table。例如
ID1 ID2
01A XY1
01B XY4
...
两个 ID 列中都有重复的值,并且已决定仅保留两个 ID 之间存在一对一匹配的情况。即,如果任何 ID1 值与多个 ID2 值匹配,则删除具有该 ID1 值的所有行。反之亦然。
我使用 dplyr
编写了一些有效的代码:
df %>%
group_by(ID1) %>%
filter(n_distinct(ID2)==1) %>%
distinct() %>%
filter(!is.na(ID2)) %>%
group_by(ID2) %>%
filter(n_distinct(ID1)==1) %>%
distinct() %>%
filter(!is.na(ID1))
但是,由于 table 的大小,这对 运行 来说相当慢。我正在尝试弄清楚如何使用 data.table
来做同样的事情。我认为它必须使用 unique
和 uniqueN
的某种组合,但似乎不太正确。
非常感谢任何帮助。
在data.table
中,你可以做-
library(data.table)
setDT(df)
na.omit(unique(df[, .SD[uniqueN(ID2) == 1], ID1][,
.SD[uniqueN(ID1) == 1], ID2]))
我们可以做到
library(data.table)
tmp <- setDT(df)[df[, .I[uniqueN(ID2)== 1], ID1]$V1]
na.omit(unique(tmp[tmp[, .I[uniqueN(ID1) == 1], ID2]$V1]))