データフレームをサブセット化して、3つの列の一意の組み合わせを持つ行のみを含めたいと思います。私の状況は this の質問で提示された状況と似ていますが、データ内の他の列も保持したいと思います。これが私の例です:
> df
v1 v2 v3 v4 v5
1 7 1 A 100 98
2 7 2 A 98 97
3 8 1 C NA 80
4 8 1 C 78 75
5 8 1 C 50 62
6 9 3 C 75 75
要求された出力は次のようなものになります。v1、v2、v3のみに基づいた一意のケースを探しています。
> df.new
v1 v2 v3 v4 v5
1 7 1 A 100 98
2 7 2 A 98 97
3 8 1 C NA 80
6 9 3 C 75 75
一意ではない行を回復できたら、それも素晴らしいでしょう:
> df.dupes
v1 v2 v3 v4 v5
3 8 1 C NA 80
4 8 1 C 78 75
5 8 1 C 50 62
私はSQLでこれを行う方法に関連する質問を見ました( here )が、Rではこれを取得できません。それは簡単ですが、unique()とsubset()hasn実りありませんでした。前もって感謝します。
duplicated()
関数を使用して、一意の組み合わせを見つけることができます。
> df[!duplicated(df[1:3]),]
v1 v2 v3 v4 v5
1 7 1 A 100 98
2 7 2 A 98 97
3 8 1 C NA 80
6 9 3 C 75 75
重複のみを取得するには、双方向で確認できます。
> df[duplicated(df[1:3]) | duplicated(df[1:3], fromLast=TRUE),]
v1 v2 v3 v4 v5
3 8 1 C NA 80
4 8 1 C 78 75
5 8 1 C 50 62
dplyr
を使用すると、次のことができます。
library(dplyr)
# distinct
df %>%
distinct(v1, v2, v3, .keep_all = T)
# non-distinct only
df %>%
group_by(v1, v2, v3) %>%
filter(n() > 1)
# exclude any non-distinct
df %>%
group_by(v1, v2, v3) %>%
filter(n() == 1)
plyr
パッケージを使用できます:
library(plyr)
ddply(df, c("v1","v2","v3"), head, 1)
# v1 v2 v3 v4 v5
# 1 7 1 A 100 98
# 2 7 2 A 98 97
# 3 8 1 C NA 80
# 4 9 3 C 75 75
ddply(df, c("v1","v2","v3"), function(x) if(nrow(x)>1) x else NULL)
# v1 v2 v3 v4 v5
# 1 8 1 C NA 80
# 2 8 1 C 78 75
# 3 8 1 C 50 62
ええ、データが多すぎる場合、plyrとddplyの使用は非常に遅くなります。
この種のものを試してみてください:
df[ cbind( which(duplicated(df[1:3])), which(duplicated(df[1:3], fromLast=TRUE))),]
または::
from = which(duplicated(df[1:3])
to = which(duplicated(df[1:3], fromLast=TRUE))
df[cbind(from,to),]
ほとんどの場合、shdはより高速になります。
それをテストして、私たちに知らせてください
いくつかのエラーがありますが、アイデアが得られれば修正できると思います。
また、ユニークですべてを試してみてください
エレガントではないが機能的な方法は、特定の行のエントリを貼り付けて、一意の(または一意ではない)行を見つけることです。
df.vector=apply(df,1,FUN=function(x) {paste(x,collapse="")})
df.table=table(df.vector)
次に、次のようなもので重複のインデックスを取得します。
which(df.vector%in%names(which(df.table>1)))