・お題:ベクトルの要素の重複を削除したり、data.frameの行の重複を削除する方法をいつも忘れるので、メモしておきたい。
# ライブラリ読み込み
library(tidyverse)
# ベクトルの要素の重複を何とかする。
# ベクトル作成
test <- c("A", "A", "A", "B", "B", "B", "C", "C", "C")
test
[1] "A" "A" "A" "B" "B" "B" "C" "C" "C"
# 被っているのを削る。
unique(test)
[1] "A" "B" "C"
# 例えば、ベクトルの要素に名前がついていると、unique関数だと名前が消える。
names(test) <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
unique(test)
[1] "A" "B" "C"
# duplicated関数でどれがダブっているか判定して、ダブっていないものを取り出すことにする。最初に出てくるときにダブっていない判定(FALSE)になる。
duplicated(test)
[1] FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE
test[!duplicated(test)] # ビックリマークでT/Fをひっくり返す
1 4 7
"A" "B" "C"
# データフレームでもやってみる。
# データフレーム作成
df <- data.frame(
id = c(1, 2, 3, 4, 5, 4, 3, 2, 1),
value = c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
score = c(1, 2, 3, 1, 2, 3, 1, 2, 3)
)
df
# 先ほどのduplicated関数を使って、value列が被っているものを除去する。
df[!duplicated(df$value),]
# data.frameの場合、重複判定の対象になる情報が複数あるので、それらのダブりっぷりを加味して取り出す必要がある。ちょっとめんどくさい。例えば、idとvalueを使ってそれらが一致しているものをはじくと、以下のような感じ。
df[!(duplicated(df$id) & duplicated(df$value)),]
# dplyrパッケージのdistinct関数を使うと、もうちょっと書きやすい。distnct関数でいろいろやってみる。
# valueの重複を削除してみる。そのままだと、value以外の列がどっか行く。
df %>%
dplyr::distinct(value)
# 引数.keep_allにTRUEを与えると、他の列も残る。
df %>%
dplyr::distinct(value, .keep_all = TRUE)
# 複数列を対象にdistinct関数を実行する場合、引数に列名をつらつらと与えれば良い。
df %>%
dplyr::distinct(id, value, .keep_all = TRUE)
# 例えば、重複している場合は中央値を代表値としてとってきたい、ということがあるとする。その場合、重複上の削除というよりも、グループごとの集計のニュアンスが強くなる。
# そのため、dplyrパッケージのgroup_byやsummarizeを使う。
df %>%
dplyr::group_by(value) %>%
dplyr::summarise(score = median(score))
# 複数条件でgroup_byするなら以下のような感じ。ungroupすることで、group化を解除できる。そのあとただのdata.frameとして何かに利用するならやっとく。
df %>%
dplyr::group_by(id, value) %>%
dplyr::summarise(score = median(score)) %>%
ungroup()
おわり