【问题标题】:Removing duplicates based on common and different in values基于共同值和不同值删除重复项
【发布时间】:2016-05-09 20:48:28
【问题描述】:

我有一个这样的数据表

dt <- data.table(date=c('d1','d2','d3','d1','d2','d3'),v1=c('a','a','b','a','b','b'),v2=c(2,2,4,2,4,4))
   date v1 v2
1:   d1  a  2
2:   d2  a  2 <-need to remove this 
3:   d3  b  4 
4:   d1  a  2
5:   d2  b  4 <-need to remove this 
6:   d3  b  4

我的实际数据包含构成唯一条件的 1600 万行和 5 列,以及一个日期列。我想删除具有相同公共值的重复项(在 v1、v2 中)但仅当它们的日期(日期)不同时。

样本输出

   date v1 v2
1:   d1  a  2
2:   d3  b  4
3:   d1  a  2
4:   d3  b  4

我尝试了“重复”功能,但找不到删除重复项的正确方法。感谢任何帮助。

【问题讨论】:

  • 我实际上不明白您要识别重复项的规则。为什么要在第 1 行和第 4 行相同时保留它们?
  • 我想保留它们,因为它们的日期相同。
  • @pauljeba 你能否澄清一下你想对日期相同但 v1/v2 值不同的行做什么?例如,dt &lt;- data.table(date=c('d1','d2','d3','d1','d2','d3', 'd4', 'd4'), v1=c('a','a','b','a','b','b', 'a', 'b'),v2=c(2,2,4,2,4,4, 1, 2)) 的期望输出是什么?
  • @cath 那么这些记录应该被持久化。您的测试集的示例输出将是; data.table(date=c('d1','d3','d1','d3', 'd4', 'd4'), v1=c('a','b','a','b', 'a', 'b'),v2=c(2,4,2,4, 1, 2))
  • @akrun 无需删除您的答案:它显示了一种适用于原始问题的不错的替代方法

标签: r duplicates data.table


【解决方案1】:

如果我“翻译”正确,您需要变量 v1v2 不重复的行,或者这些变量但变量 date 重复的行

dt[!duplicated(dt[, .(v1, v2)]) | 
   (duplicated(dt[, .(v1, v2)]) & duplicated(dt[, .(date, v1, v2)]))]
#   date v1 v2
#1:   d1  a  2
#2:   d3  b  4
#3:   d1  a  2
#4:   d3  b  4

正如@Arun 所提到的,另一个避免复制dt 的更好方法是利用duplicated.data.tableby 参数:

dt[!duplicated(dt, by=c("v1", "v2")) | 
   (duplicated(dt, by=c("v1", "v2")) & duplicated(dt, by=c("date", "v1", "v2")))]

【讨论】:

  • 感谢@akrun,我只是怀疑您的解决方案是否符合预期:它保留了好的复制品,这是肯定的,但是(除非我遗漏了什么),未能保留未复制的值,对于同一日期。 (你可以看看我在Q下发表的评论)
  • 我理解您的担忧。通过一个简单的示例,要知道 OP 期望什么并不容易。正如我们所说,对这个问题还有另一种解释(尽管它得到了赞成票)
  • 谢谢@Cath!很好地阐明了我需要的逻辑条件。
  • duplicated.data.table 有一个 by 参数。 .(v1,v2) 返回一个副本。
  • 感谢@Arun,所以dt[!duplicated(dt, by=c("v1", "v2")) | (duplicated(dt, by=c("v1", "v2")) &amp; duplicated(dt, by=c("date", "v1", "v2")))] 应该在不复制表格的情况下做同样的事情吗?
【解决方案2】:

我理解这个问题的方式是,对于每个 v1/v2 组合,只需要保留出现次数最多的日期。为此,您可以这样做:

dt[, n:=.N, by = .(date,v1,v2)][, .SD[n==max(n)], by = .(v1,v2)][, n:= NULL][]

给出:

   v1 v2 date
1:  a  2   d1
2:  a  2   d1
3:  b  4   d3
4:  b  4   d3

使用提供的示例数据,这给出了与@Cath 和@Akrun 相同的结果。


但是,使用以下数据(@Cath 在问题的 cmets 中发布):

dt1 <- data.table(date=c('d1','d2','d3','d1','d2','d3','d4','d4'), 
                  v1=c('a','a','b','a','b','b','a','b'),
                  v2=c(2,2,4,2,4,4,1,2))

现在@akrun 的方法会给出不同的结果:

> dt1[!duplicated(dt1[, .(v1, v2)]) | (duplicated(dt1[, .(v1, v2)]) & duplicated(dt1[, .(date, v1, v2)])), ]
   date v1 v2
1:   d1  a  2
2:   d3  b  4
3:   d1  a  2
4:   d3  b  4
5:   d4  a  1
6:   d4  b  2
> dt1[, if(uniqueN(.SD, by = c('v1', 'v2'))==1) .SD ,by = date]
   date v1 v2
1:   d1  a  2
2:   d1  a  2
3:   d3  b  4
4:   d3  b  4
> dt1[, n:=.N, by = .(date,v1,v2)][, .SD[n==max(n)], by = .(v1,v2)][, n:= NULL][]
   v1 v2 date
1:  a  2   d1
2:  a  2   d1
3:  b  4   d3
4:  b  4   d3
5:  a  1   d4
6:  b  2   d4

因此,欢迎对 OP 的需求提出更明确的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多