繁体   English   中英

在 r data.table 中查找重复组

[英]Find repeating groups in r data.table

我需要在 r 数据表中识别和删除重复的记录组(但我认为问题在任何编程语言中都是相同的),结构如下:

输入数据表

组由 var1 和 var2 中的值标识,如果它们具有相同的大小并且在 var2 和 var3 中包含相同的值,则它们是重复的(var3 中的值是由 var1 和 var2 标识的更大组的共同点)。

因此,在示例中,2 个红色组是重复的,但对 (red,blue) 和对 (red,brown) 不是。

我的解决方案是将表格转换为宽格式

转置数据表

然后执行unique(dt[,var1:=NULL])并转回长格式(此时我不再需要 var1 )。

问题是我的真实表格有 165,391,868 条记录,这不是一次性任务,而是每周一次的任务,表格大小相似,时间有限。

我尝试将表拆分成块,附加它们,然后进行重复数据删除,但第一个转置现在已经运行了 2 小时以上!

任何替代和最快的解决方案? 非常感谢!

创建示例表的代码:

dt <- data.table(
var1=c(
    "value1_1",
    "value1_1",
    "value1_1",
    "value1_2",
    "value1_2",
    "value1_2",
    "value1_2",
    "value1_3",
    "value1_3",
    "value1_3",
    "value1_4",
    "value1_4",
    "value1_4",
    "value1_5",
    "value1_5",
    "value1_5",
    "value1_5"),
var2=c(
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1",
    "value2_1"),
var1=c(
    "value3_1",
    "value3_2",
    "value3_3",
    "value3_2",
    "value3_4",
    "value3_5",
    "value3_6",
    "value3_1",
    "value3_2",
    "value3_3",
    "value3_1",
    "value3_2",
    "value3_4",
    "value3_1",
    "value3_2",
    "value3_3",
    "value3_5"))

这里有 2 个其他选项:

1) 将var3折叠成单个值以进行连接

lu <- dt[, paste(var3, collapse=""), .(var1, var2)]

samegrp <- lu[lu, on=.(V1)][
    var1!=i.var1 & var2==i.var2, 
    .(var1=c(var11, var12), g=.GRP),
    .(var11=pmin(var1, i.var1), var12=pmax(var1, i.var1), var2)]

dt[samegrp, on=.(var1, var2), g := g]

output:

        var1     var2     var3  g
 1: value1_1 value2_1 value3_1  1
 2: value1_1 value2_1 value3_2  1
 3: value1_1 value2_1 value3_3  1
 4: value1_2 value2_1 value3_2 NA
 5: value1_2 value2_1 value3_4 NA
 6: value1_2 value2_1 value3_5 NA
 7: value1_2 value2_1 value3_6 NA
 8: value1_3 value2_1 value3_1  1
 9: value1_3 value2_1 value3_2  1
10: value1_3 value2_1 value3_3  1
11: value1_4 value2_1 value3_1 NA
12: value1_4 value2_1 value3_2 NA
13: value1_4 value2_1 value3_4 NA
14: value1_5 value2_1 value3_1 NA
15: value1_5 value2_1 value3_2 NA
16: value1_5 value2_1 value3_3 NA
17: value1_5 value2_1 value3_5 NA

2)匹配计数:

setkey(dt, var1, var2, var3)
count <- dt[, .N, .(var1, var2)]

matches <- dt[dt, on=.(var2, var3), allow.cartesian=TRUE, nomatch=0L][
    var1!=i.var1,
    .(N=.N / 2, g=.GRP),
    .(var11=pmin(i.var1, var1), var12=pmax(i.var1, var1), var2)]

matches[count, on=.(var11=var1, var2, N), nomatch=0L][
    count, on=.(var12=var1, var2, N), nomatch=0L]

output:

      var11    var12     var2 N g
1: value1_1 value1_3 value2_1 3 1

第二种方法更密集 memory,因此可能会更慢。 但实际性能确实取决于实际数据集的特性。 例如,列的数据类型、 var1var2的唯一对数、 var3的唯一值的数量等。

我想我有一个解决方案,但如果它不起作用,请告诉我,我会再次破解。

我刚刚通过将 var2 添加到 id 列来响应您的评论进行编辑

首先为基于 var1 和 var2 的组创建一个列

dt[,group:=paste0(var1, var2)]

然后根据 var3 和大小创建一个 id

dt[,id:=paste0(paste(sort(var3), collapse=""), var2, .N), by=group]

然后你 label 每个组都有一个数字,基于它是第一次,第二次,第三次等你看到一个组的 id

dt[,groupN:=as.numeric(factor(group)), by=id]

然后仅在您第一次看到每个组时保留

dt[groupN==1]

这行得通,但我不知道它的效率(老实说,它可能更慢,但它是一种不同的方法)。 我已经为另一个项目构建了多功能滤波器 function,我想到在这里使用它。 multifilter 根据您提供给它的任何列中找到的变量的唯一组合将 dataframe 拆分为数据框列表。 然后我们检查重复的 var 3 cols 并删除它们。 最后数据集被反弹。

multifilter <- function(data,filterorder){  
  newdata <- list(data)
  for(i in rev(filterorder)){
    newdata <- unlist(lapply(sort(unique(data[,i])), function(x) lapply(newdata, function(y) y[y[,i]==x,])),recursive=F)
  }
  return(newdata[sapply(newdata,nrow)>=1])
}


filtereddt <- multifilter(dt,c("var1","var2"))
filtereddt <- filtereddt[-duplicated(lapply(filtereddt, function(x) x[,3]))]
filtereddt <- do.call(rbind, filtereddt)[,-1]

output:

> filtereddt
       var2     var3
4  value2_1 value3_2
5  value2_1 value3_4
6  value2_1 value3_5
7  value2_1 value3_6
8  value2_1 value3_1
9  value2_1 value3_2
10 value2_1 value3_3
11 value2_2 value3_1
12 value2_2 value3_2
13 value2_2 value3_4
14 value2_1 value3_1
15 value2_1 value3_2
16 value2_1 value3_3
17 value2_1 value3_5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM