web-dev-qa-db-ja.com

重複した行のインデックスを見つける

Rで複製された関数は、重複行検索を実行します。重複を削除する場合は、df[!duplicated(df),]と記述するだけで、重複がデータフレームから削除されます。

しかし、重複データのインデックスを見つける方法は? duplicatedがいくつかの行でTRUEを返す場合、これはデータフレーム内のこのような行の2回目の出現であり、そのインデックスは簡単に取得できることを意味します。この行の最初の発生のインデックスを取得する方法は?または、言い換えれば、複製された行と同一のインデックス?

Data.frameでループを作成できましたが、この質問にはもっとエレガントな答えがあると思います。

64
annndrey

これは論理インデックスベクトルを返します。

duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1]

以下に例を示します。

df <- data.frame(a = c(1,2,3,4,1,5,6,4,2,1))

duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1]
#[1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

which(duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1])
#[1]  1  2  4  5  8  9 10

更新(コメントに基づく):
fromLast = TRUEを関数の引数として使用すると、コマンドの複雑さを軽減できます。これは、2つの反転ベクトルを作成するよりも簡単です。

duplicated(df) | duplicated(df, fromLast = TRUE)

duplicated(df) | duplicated(df, fromLast = TRUE)
#[1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

使い方?

関数duplicatedは、元のデータフレームと行の順序が逆のデータフレームの両方に適用されます。後者の出力は再び逆になります。元のデータで重複する値が最初に現れるのは、逆バージョンで最後に現れることに注意してください。その後、両方のベクトルは|を使用して結合されます。これは、少なくとも一方のTRUEが重複値を示すためです。

90
Sven Hohenstein

keyed data.tableを使用している場合、次のエレガントな構文を使用できます

_library(data.table)
DT <- data.table(A = rep(1:3, each=4), 
                 B = rep(1:4, each=3), 
                 C = rep(1:2, 6), key = "A,B,C")

DT[unique(DT[duplicated(DT)]),which=T]
_

開梱するには

  • DT[duplicated(DT)]は、重複する行をサブセット化します。

  • unique(...)は、複製された行の一意の組み合わせのみを返します。これは、2つ以上の重複(重複、たとえば3重複など)がある場合に対処します。

  • _DT[..., which = T]_は、重複した行を元の行とマージし、_which=T_は行番号を返します(_which = T_を指定しない場合は、データを返します)。

また使用することができます

_ DT[,count := .N,by = list(A,B,C)][count>1, which=T]
_
18
mnel