删除所有基于多个变量的重复记录

Remove all records that have duplicates based on more than one variables

我有这样的数据

df <- data.frame(var1 = c("A", "A", "B", "B", "C", "D", "E"), var2 = c(1, 2, 3, 4, 5, 5, 6 ))
#   var1 var2
# 1    A    1
# 2    A    2
# 3    B    3
# 4    B    4
# 5    C    5
# 6    D    5
# 7    E    6

A 映射到 1, 2

B 映射到 3, 4

CD 都映射到 5(反之亦然:5 映射到 CD

E 唯一地 映射到 6 6唯一映射到E

我想过滤数据集,以便只有

   var1 var2
7    E    6

返回。 base 欢迎使用 tidyverse 解决方案。

我试过了

unique(df$var1, df$var2)
df[!duplicated(df),]
df %>% distinct(var1, var2)

但没有得到想要的结果。

使用自定义函数来确定映射是否唯一,您可以像这样获得所需的结果:

df <- data.frame(
  var1 = c("A", "A", "B", "B", "C", "D", "E"),
  var2 = c(1, 2, 3, 4, 5, 5, 6)
)

is_unique <- function(x, y) ave(as.numeric(factor(x)), y, FUN = function(x) length(unique(x)) == 1)

df[is_unique(df$var2, df$var1) & is_unique(df$var1, df$var2), ]
#>   var1 var2
#> 7    E    6

使用 igraph::components.

将数据表示为图形并获取连通分量:

library(igraph)
g = graph_from_data_frame(df)
cmp = components(g)

抓取簇大小 (csize) 为 2 的组件。将顶点输出为两列字符矩阵:

matrix(names(cmp$membership[cmp$membership %in% which(cmp$csize == 2)]),
       ncol = 2, dimnames = list(NULL, names(df))) # wrap in as.data.frame if desired
#      var1 var2
# [1,] "E"  "6"

或者,使用相关顶点的名称来索引原始数据框:

v = names(cmp$membership[cmp$membership %in% which(cmp$csize == 2)])
df[df$var1 %in% v[1:(length(v)/2)], ]
#   var1 var2
# 7    E    6

可视化连接:

plot(g)

另一个igraph选项

decompose(graph_from_data_frame(df)) %>%
  subset(sapply(., vcount) == 2) %>%
  sapply(function(g) names(V(g)))

这给出了

     [,1]
[1,] "E"
[2,] "6"

基础 R 解决方案:

df[!(duplicated(df$var1) | duplicated(df$var1, fromLast = TRUE) | 
       duplicated(df$var2) | duplicated(df$var2, fromLast = TRUE)), ]
  var1 var2
7    E    6