web-dev-qa-db-ja.com

data.table内の重複した/一意でない行をフィルターで除外する

約250万行の_data.table_テーブルがあります。 2つの列があります。両方の列に重複している行を削除したい。以前は、data.frameの場合はdf -> unique(df[,c('V1', 'V2')])を実行していましたが、これはdata.tableでは機能しません。 unique(df[,c(V1,V2), with=FALSE])を試しましたが、行全体ではなく、data.tableのキーに対してのみ動作するようです。

助言がありますか?

乾杯、デイビー

_>dt
      V1   V2
[1,]  A    B
[2,]  A    C
[3,]  A    D
[4,]  A    B
[5,]  B    A
[6,]  C    D
[7,]  C    D
[8,]  E    F
[9,]  G    G
[10,] A    B
_

上記のdata.tableでは、_V2_がテーブルキーであり、行4、7、および10のみが削除されます。

_> dput(dt)
structure(list(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", 
"E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", 
"G")), .Names = c("V1", "V2"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x7fb4c4804578>, sorted = "V2")
_
68
Davy Kavanagh

v1.9.8以前

?unique.data.tableから、データテーブルでuniqueを呼び出すことはキーでのみ機能することは明らかです。つまり、uniqueを呼び出す前に、すべての列のキーをリセットする必要があります。

library(data.table)
dt <- data.table(
  V1=LETTERS[c(1,1,1,1,2,3,3,5,7,1)],
  V2=LETTERS[c(2,3,4,2,1,4,4,6,7,2)]
)

1つの列をキーとしてuniqueを呼び出す:

setkey(dt, "V2")
unique(dt)
     V1 V2
[1,]  B  A
[2,]  A  B
[3,]  A  C
[4,]  A  D
[5,]  E  F
[6,]  G  G

v1.9.8 +の場合

From ?unique.data.tableデフォルトでは、すべての列が使用されます(?unique.data.frameと一致)

unique(dt)
   V1 V2
1:  A  B
2:  A  C
3:  A  D
4:  B  A
5:  C  D
6:  E  F
7:  G  G

または、特定の列の一意の組み合わせを取得するためにby引数を使用します(以前はキーが使用されていたように)

unique(dt, by = "V2")
   V1 V2
1:  A  B
2:  A  C
3:  A  D
4:  B  A
5:  E  F
6:  G  G
81
Andrie

あなたの例のdata.tableで...

_> dt<-data.table(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", "E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", "G"))
> setkey(dt,V2)
_

次のテストを検討してください。

_> haskey(dt) # obviously dt has a key, since we just set it
[1] TRUE

> haskey(dt[,list(V1,V2)]) # ... but this is treated like a "new" table, and does not have a key
[1] FALSE

> haskey(dt[,.SD]) # note that this still has a key
[1] TRUE
_

したがって、テーブルの列をリストし、そのunique()を取得できます。すべての列にキーを設定したり、(NULLに設定して)キーを削除する必要はありません。 @Andrieのソリューションに必要です(および@MatthewDowleにより編集)。 @Popと@Rahulによって提案されたソリューションは、私にとってはうまくいきませんでした。

最初の試行と非常によく似た以下の試行3を参照してください。あなたの例は明確ではなかったので、なぜそれがうまくいかなかったのか分かりません。また、質問を投稿したのは数か月前だったので、おそらく_data.table_が更新されましたか?

_> unique(dt) # Try 1: wrong answer (missing V1=C and V2=D)
   V1 V2
1:  B  A
2:  A  B
3:  A  C
4:  A  D
5:  E  F
6:  G  G

> dt[!duplicated(dt)] # Try 2: wrong answer (missing V1=C and V2=D)
   V1 V2
1:  B  A
2:  A  B
3:  A  C
4:  A  D
5:  E  F
6:  G  G

> unique(dt[,list(V1,V2)]) # Try 3: correct answer; does not require modifying key
   V1 V2
1:  B  A
2:  A  B
3:  A  C
4:  A  D
5:  C  D
6:  E  F
7:  G  G

> setkey(dt,NULL)
> unique(dt) # Try 4: correct answer; requires key to be removed
   V1 V2
1:  B  A
2:  A  B
3:  A  C
4:  A  D
5:  C  D
6:  E  F
7:  G  G
_
7
dnlbrky

unique(df)はあなたの例で動作します。

1
Pop

これはあなたのために働くはずです

dt <- unique(dt, by = c('V1, 'V2'))
0
Magma