2

私のテーブルには 2 つの ID があります。1 番目の ID の値ごとに、2 番目の ID の値が異なる 2 つの行が同一かどうかを調べたい (2 番目の ID の列を除く)。私のテーブルと非常によく似た(しかしはるかに小さい)テーブルは次のとおりです。

library(data.table)

DT <- data.table(id   = rep(LETTERS, each=10),
                 var1 = rnorm(260),
                 var2 = rnorm(260))


DT[, id2 := sample(c("A","B"), 10, T), by=id] # I need this to simulate different 
                                              # distribution of the id2 values, for
                                              # each id value, like in my real table

setkey(DT, id, id2)

DT$var1[1] <- DT$var1[2] # this simulates redundances
DT$var2[1] <- DT$var2[2] # inside same id and id2

DT$var1[8] <- DT$var1[2] # this simulates two rows with different id2
DT$var2[8] <- DT$var2[2] # and same var1 and var2. I'm after such rows!

> head(DT, 10)
    id           var1           var2 id2
 1:  A  0.11641260243  0.52202152686   A
 2:  A  0.11641260243  0.52202152686   A
 3:  A -0.46631312530  1.16263285108   A
 4:  A -0.01301484819  0.44273945065   A
 5:  A  1.84623329221 -0.09284888054   B
 6:  A -1.29139503119 -1.90194818212   B
 7:  A  0.96073555968 -0.49326620160   B
 8:  A  0.11641260243  0.52202152686   B
 9:  A  0.86254993530 -0.21280899589   B
10:  A  1.41142798959  1.13666002123   B

私は現在このコードを使用しています:

res <- DT[, {a=unique(.SD)[,-3,with=F]   # Removes redundances like in row 1 and 2
                                         # and then removes id2 column.
             !identical(a, unique(a))},  # Looks for identical rows
          by=id]                         # (in var1 and var2 only!)

> head(res, 3)
   id    V1
1:  A  TRUE
2:  B FALSE
3:  C FALSE

すべてが機能しているように見えますが、実際のテーブル (ほぼ 80M 行と 4,5M のunique(DT$id)) では、コードに 2,1 時間かかります。

上記のコードを高速化するためのヒントはありますか? 最終的に、data.table機能を活用するために必要なベスト プラクティスに従っていないのでしょうか? よろしくお願いします!

編集:

私のコードを @Arun のコードと比較するタイミング:

DT <- data.table(id   = rep(LETTERS,each=10000),
                 var1 = rnorm(260000),
                 var2 = rnorm(260000))

DT[, id2 := sample(c("A","B"), 10000, T), by=id] # I need this to simulate different 

setkey(DT)

> system.time(unique(DT)[, any(duplicated(.SD)), by = id, .SDcols = c("var1", "var2")])
   user  system elapsed 
   0.48    0.00    0.49 
> system.time(DT[, {a=unique(.SD)[,-3,with=F]   
+                   any(duplicated(a))}, 
+    by=id])
   user  system elapsed 
   1.09    0.00    1.10 

欲しかったものを手に入れたと思います!

4

1 に答える 1