如何从具有相同列的列表中删除数据框?

时间:2020-07-28 13:49:51

标签: r list match unique

我有一个很大的列表,其中包含100多个数据帧。我希望此列表仅显示唯一的数据帧。解决方案非常简单:unique(listname)

但是,由于数据非常混乱,因此有时数据帧与其他数据帧相同,但是添加了一个列。在这种情况下,unique(listname)将不起作用。

我正在尝试使用for循环来解决此问题。但是我的解决方案似乎效率很低(并且无法正常工作)。

可复制的示例

df1 <- data.frame(id = c(151, 151, 151, 151, 151), name = c("Jan Slagter", "Jan Smit", "Monica Geuzen", "Marco Borsato", "Rafael van der Vaart"), status = c(5, 1, 2, 4, 5))

df2 <- data.frame(id = c(152, 152, 152), name = c("Jan van Halst", "Herman van der Zandt", "Philip Freriks"), status = c(5, 5, 5))

df3 <- data.frame(id = c(151, 151, 151, 151, 151), name = c("Jan Slagter", "Jan Smit", "Monica Geuzen", "Marco Borsato", "Rafael van der Vaart"), status = c(5, 1, 2, 4, 5), control = c(TRUE, FALSE, TRUE, TRUE, FALSE))

famous <- list(df1, df2, df3)

在这种情况下,unique(famous)仍将返回famous。就我而言,我想从新创建的df3列表中删除famous。我最远的尝试仅在第一列(id)与列表中的其他任何id列匹配时返回错误:

threshold <- min(sapply(famous, nrow))
for(i in 1:length(famous)){
  for(j in 1:length(famous)){
    if(i != j){
temp <- famous[[i]][[1]] %in% famous[[j]][[1]]
stopifnot(length(temp[temp == TRUE]) < threshold)
    }
  }
}

这绝对不是最干净的解决方案,也根本不是我想要的。但是请注意,我想要一个解决方案,在该列表中,我想将数据框排除在整列与其他数据框的同一整列匹配的列表中。预先谢谢你。

1 个答案:

答案 0 :(得分:0)

您可以通过首先使用unique删除相同的帧来稍微缩小搜索空间,然后对于列表中的每个数据帧仅检查其他包含其所有列名且具有相同编号的帧。行。然后,通过索引数据帧的列名将这些帧中的每一个子集化,并检查结果是否为identical

famous <- unique(famous)

remove_these <- unlist(lapply(famous, function(x)
  { 
    ss1 <- sapply(famous,      function(i) nrow(i) == nrow(x) & 
                                           all(names(x) %in% names(i)) &
                                           !identical(i, x))
    
    ss2 <- sapply(famous[ss1], function(i) identical(i[names(x)], x))
    
    if(length(ss2)) which(ss1)[ss2]
  }))

remove_these
#> [1] 3

所以我们可以做

famous[-remove_these]
#> [[1]]
#>    id                 name status
#> 1 151          Jan Slagter      5
#> 2 151             Jan Smit      1
#> 3 151        Monica Geuzen      2
#> 4 151        Marco Borsato      4
#> 5 151 Rafael van der Vaart      5
#> 
#> [[2]]
#>    id                 name status
#> 1 152        Jan van Halst      5
#> 2 152 Herman van der Zandt      5
#> 3 152       Philip Freriks      5

如果两个数据帧有一个或多个共同的列,它将始终删除其中较大的一个。