簡體   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