从上到下删除两个未分组列中的重复项

Pur*_*mon 13 r duplicates dataframe dplyr

这是一个示例数据框,用于显示我的问题和我想要实现的目标。这里我有两列xy,我想从中删除重复项。我还有z包含行的排序排名的列。

  x   y   z
1 A   BB  8
2 B   BB  7.5
3 B   AA  6.2
4 B   CC  5
5 C   DD  4
6 D   CC  3
Run Code Online (Sandbox Code Playgroud)

我试图同时查看两者,每次两列中都有重复项时,然后删除该行并继续xy

我正在寻找的最终结果是

  x   y   z
1 A   BB  8
3 B   AA  6.2
5 C   DD  4
6 D   CC  3
Run Code Online (Sandbox Code Playgroud)

BB列中的第二个y被删除。然后,该B - AA行不会被删除,因为逐行向下,它现在是列B中的第一行x。这是针对大型数据集的,因此不幸的是我无法手动完成。

我并不是想将这两列组合在一起。我也不想一次删除一列的重复项,因为如果这样做的话,就会删除太多的观察结果。

如何才能实现这一目标?

asd*_*-tm 6

由于我们需要同时检查两列,我怀疑我们是否可以使用顺序检查 x 和 y 列,duplicated()因此这是我的报价较慢但可能更可靠:

  i <- 2
  repeat {
    row_removed <- F
    if(df[i,]$x %in% df[1:(i-1),"x"]) {
      df <- df[-i,]
      row_removed <- T
    }
    if (i>nrow(df)) break
    if(df[i,]$y %in% df[1:(i-1),"y"]) {
      df <- df[-i,]
      row_removed <- T
    }
    if (!row_removed) i <- i + 1
    if (i>nrow(df)) break
  }
Run Code Online (Sandbox Code Playgroud)

结果:

  x  y   z
1 A BB 8.0
3 B AA 6.2
5 C DD 4.0
Run Code Online (Sandbox Code Playgroud)

对于编辑后的数据集,它还返回 OP 预期的结果:

  x  y   z
1 A BB 8.0
3 B AA 6.2
5 C DD 4.0
6 D CC 3.0
Run Code Online (Sandbox Code Playgroud)


Pur*_*mon 0

这解决了我的问题。

remove_top_duplicate <- function(tempdf) {
  tempdf <- tempdf %>% 
    group_by(x) %>% 
    mutate(xrep = row_number()) %>% 
    ungroup() %>% 
    group_by(y) %>% 
    mutate(yrep = row_number()) %>% 
    ungroup()

  if(!(any(tempdf$xrep > 1)) & !(any(tempdf$yrep > 1))){
    break
  }

  tempdf <- slice(tempdf, -which(xrep > 1 | yrep > 1)[1])
  return(tempdf)
}

while(TRUE){
  df <- remove_top_duplicate(df)
  if(!(any(df$xrep > 1)) & !(any(df$yrep > 1))){
    print("Finished")
    break
  }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个函数,它接受日期范围,并 row_numbers()首先为 x 改变列,然后为 y 改变列。这样我们就有了两列xrepyrep我们可以在其中找到最上面的重复项。然后我只对发现的大于的第一行进行切片,1然后返回数据帧。因为这是一个函数,所以我只是在某种while(TRUE)情况下运行它,然后等待直到重复列中没有2's,此时我们知道不再有重复项。

这是第一次运行后的示例。然后,由于列2中的 ,它将对第二行进行切片yrep。之后,它返回数据帧,然后重复重新计算的过程。然后再切片。

  x     y       z     xrep  yrep
1 A     BB      8       1     1
2 B     BB      7.5     1     2
3 B     AA      6.2     2     1
4 B     CC      5       3     1
5 C     DD      4       1     1
6 D     CC      3       1     2
Run Code Online (Sandbox Code Playgroud)

这不是一个干净的解决方案,但它可以完成工作。