私のテーブルには 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
欲しかったものを手に入れたと思います!