删除所有重复行,除非有“相似”行

Was*_*abi 6 r data.table

我有以下内容data.table

library(data.table)
dt = data.table(c(1, 1, 1, 2, 2, 2, 2, 3, 4),
                c(4, 4, 4, 5, 5, 6, 7, 4, 5))
   V1 V2
1:  1  4
2:  1  4
3:  1  4
4:  2  5
5:  2  5
6:  2  6
7:  2  7
8:  3  4
9:  4  5
Run Code Online (Sandbox Code Playgroud)

我想研究V2给定的不同值V1。但是,如果V2给定的所有值V1都相同,那我就不会感兴趣,因此我想删除这样的行。

在上面的示例中,前三行完全相同(V1=1V2=4),因此我希望将其删除。

但是,接下来的四行包括两个相同的行,其他具有不同的V2。在这种情况下,我想说明的三个可能的值V2给出V1 = 2(2, 5)(2, 6)(2, 7)

最后两行具有唯一的V1:属于“所有行都完全相同”的类别,因此也应将其删除。

我能想到的最好的就是这个答案

dt[!duplicated(dt) & !duplicated(dt, fromLast = TRUE), ]
   V1 V2
1:  2  6
2:  2  7
3:  3  4
4:  4  5
Run Code Online (Sandbox Code Playgroud)

显然这是不令人满意的:由于(2,5)对是重复的,因此删除了对,(3,4)并且(4,5)由于和对是唯一的,因此保留了和对,因此不会通过任何duplicated()传递来标记。

另一个选择是简单地调用

unique(dt)
   V1 V2
1:  1  4
2:  2  5
3:  2  6
4:  2  7
5:  3  4
6:  4  5
Run Code Online (Sandbox Code Playgroud)

但它一直在(1,4)(3,4)(4,5)对我要删除。

最后,我要寻找的结果是:

   V1 V2
1:  2  5
2:  2  6
3:  2  7
Run Code Online (Sandbox Code Playgroud)

尽管任何其他格式也可以接受,例如:

   V1 V2.1 V2.2 V2.3
1:  2    5    6    7
Run Code Online (Sandbox Code Playgroud)

(显示V2每个“有趣” 的可能值V1

我无法弄清楚如何区分(1,4)大小写(所有行都是相同的)和(2,5)大小写(存在一些重复项,但是还有其他行具有相同的V1,因此我们必须删除重复项,(2,5)但保留一个副本)。

至于唯一行,我写了一个非常丑陋的电话,但是只有在唯一行的情况下,它才有效。如果有两个,例如上面的示例,它将失败。

akr*_*run 6

一种选择是对“ V1”进行分组,获得唯一元素长度大于1的分组的索引,然后取 unique

unique(dt[dt[, .(i1 = .I[uniqueN(V2) > 1]), V1]$i1])
#   V1 V2
#1:  2  5
#2:  2  6
#3:  2  7
Run Code Online (Sandbox Code Playgroud)

或如@ r2evans所述

unique(dt[, .SD[(uniqueN(V2) > 1)], by = "V1"])
Run Code Online (Sandbox Code Playgroud)

注意:OP的数据集是data.tabledata.table方法是自然的方法


如果我们需要一种tidyverse选择,可以与上述data.table选择进行比较

library(dplyr)
dt %>%
   group_by(V1) %>% 
   filter(n_distinct(V2) > 1) %>% 
   distinct()
Run Code Online (Sandbox Code Playgroud)

  • @ r2evans在[此问题](/sf/ask/3506574361/)中的一个相对较大的表上有一个基准。另一个选择(不需要更多)是`unique(dt [,if(uniqueN(V2)> 1).SD,by =“ V1”])) (3认同)
  • @ r2evans不错,但是我认为`.I`会比我以前的基准测试更快 (2认同)
  • @Wasabi的作用是“ uniqueN(V2)> 1”,对于每组“ V1”,其长度为1的逻辑向量通过用.I进行换行,给出了该V1所有行的行索引。提取行索引列`$ i1`并在`i`中使用它对子行进行子集化,并用`unique`换行 (2认同)