R duplicatedは、ベクトルまたはデータフレームの各要素が、添え字の小さい要素の複製かどうかを示すベクトルを返します。したがって、5行のデータフレームの行3、4、および5が同じであるduplicated場合、ベクトルを取得します
FALSE, FALSE, FALSE, TRUE, TRUE
しかし、この場合、私は実際に取得したい
FALSE, FALSE, TRUE, TRUE, TRUE
つまり、添え字の大きい行によって行が重複しているかどうかを知りたいのです。
R duplicatedは、ベクトルまたはデータフレームの各要素が、添え字の小さい要素の複製かどうかを示すベクトルを返します。したがって、5行のデータフレームの行3、4、および5が同じであるduplicated場合、ベクトルを取得します
FALSE, FALSE, FALSE, TRUE, TRUE
しかし、この場合、私は実際に取得したい
FALSE, FALSE, TRUE, TRUE, TRUE
つまり、添え字の大きい行によって行が重複しているかどうかを知りたいのです。
回答:
duplicatedfromLast議論があります。の「例」セクションで?duplicatedは、その使用方法を示します。呼び出すだけduplicatedで1回、二回fromLast=FALSEで1回fromLast=TRUEとされているかの行を取りますTRUE。
後半の編集:再現可能な例を提供しなかったので、@ jbaumsによる親切なイラストをここに示します
vec <- c("a", "b", "c","c","c")
vec[duplicated(vec) | duplicated(vec, fromLast=TRUE)]
## [1] "c" "c" "c"
編集:データフレームの場合の例:
df <- data.frame(rbind(c("a","a"),c("b","b"),c("c","c"),c("c","c")))
df[duplicated(df) | duplicated(df, fromLast=TRUE), ]
## X1 X2
## 3 c c
## 4 c c
duplicated(c(1,1,1))VSがduplicated(c(1,1,1,), fromLast = TRUE)与えられるc(FALSE,TRUE,TRUE)とc(TRUE,TRUE,FALSE)。TRUEどちらの場合も中間値です。撮影|両ベクターのことはできますc(TRUE,TRUE,TRUE)。
duplicated値のセットを組み立て、適用uniqueしてから、でテストする必要があります%in%。いつものように、サンプル問題はこのプロセスを生き生きとさせます。
> vec <- c("a", "b", "c","c","c")
> vec[ duplicated(vec)]
[1] "c" "c"
> unique(vec[ duplicated(vec)])
[1] "c"
> vec %in% unique(vec[ duplicated(vec)])
[1] FALSE FALSE TRUE TRUE TRUE
duplicated、uniqueそして%in%1は最初にした場合、容易にデータフレームに一般化することができpaste、異常な区切り文字で各列。(受け入れられた回答の方が優れています。)
私は同じ質問をしました、そして私が間違っていなければ、これも答えです。
vec[col %in% vec[duplicated(vec$col),]$col]
Dunnoの方が高速ですが、現在使用しているデータセットは、大きな時間ギャップを生み出すテストを実行するのに十分な大きさではありません。
vec、原子ベクトルとデータフレームの両方として使用されているようです。実際のdatframeでは失敗するのではないかと思います。
データフレーム内で重複行がで得ることができたdplyrことにより、
df = bind_rows(iris, head(iris, 20)) # build some test data
df %>% group_by_all() %>% filter(n()>1) %>% ungroup()
特定の列を除外するgroup_by_at(vars(-var1, -var2))代わりに、データをグループ化するために使用できます。
データだけでなく行インデックスが実際に必要な場合は、最初に次のように追加できます。
df %>% add_rownames %>% group_by_at(vars(-rowname)) %>% filter(n()>1) %>% pull(rowname)
n()。結果のデータフレームをグループ解除することを忘れないでください。
これが関数としての@Joshua Ulrichのソリューションです。このフォーマットでは、duplicated()を使用するのと同じ方法でこのコードを使用できます。
allDuplicated <- function(vec){
front <- duplicated(vec)
back <- duplicated(vec, fromLast = TRUE)
all_dup <- front + back > 0
return(all_dup)
}
同じ例を使用します:
vec <- c("a", "b", "c","c","c")
allDuplicated(vec)
[1] FALSE FALSE TRUE TRUE TRUE
特定の列でどの行が複製されるかに興味がある場合は、plyrアプローチを使用できます。
ddply(df, .(col1, col2), function(df) if(nrow(df) > 1) df else c())
dplyrを使用してcount変数を追加します。
df %>% add_count(col1, col2) %>% filter(n > 1) # data frame
df %>% add_count(col1, col2) %>% select(n) > 1 # logical vector
重複する行の場合(すべての列を考慮):
df %>% group_by_all %>% add_tally %>% ungroup %>% filter(n > 1)
df %>% group_by_all %>% add_tally %>% ungroup %>% select(n) > 1
これらのアプローチの利点は、カットオフとして重複の数を指定できることです。
同様の問題がありましたが、特定の列の値によって重複した行を識別する必要がありました。私は次のdplyrソリューションを思いつきました:
df <- df %>%
group_by(Column1, Column2, Column3) %>%
mutate(Duplicated = case_when(length(Column1)>1 ~ "Yes",
TRUE ~ "No")) %>%
ungroup()
コードは行を特定の列でグループ化します。グループの長さが1より大きい場合、コードはグループ内のすべての行を重複としてマークします。これが完了すると、Duplicated列をフィルタリングなどに使用できます。
x <- c(1:9, 7:10, 5:22); y <- c(letters, letters[1:5]); test <- data.frame(x, y); test[duplicated(test$x) | duplicated(test$x, fromLast=TRUE), ]、および9の彼の3つのコピーすべてを返しました。なぜそれが機能するのですか?