今回は重複するデータが存在する時の、Rでの処理方法について紹介します。
重複しているデータを見つける
まずは、今回使用するサンプルデータを作成します。
1 2 3 4 |
name <- c('Taro', 'Taro','Taro', 'Jiro', 'Jiro', 'Hanako', 'Hanako') subject <- c('English', 'Math', 'Math', 'English', 'English', 'Math', 'Math') score <- c(77, 60, 60, 75, 80, 88, 81) data <- data.frame(name, subject, score) |
下記のように名前、科目、点数が入ったデータです。
name | subject | score |
---|---|---|
Taro | English | 77 |
Taro | Math | 60 |
Taro | Math | 60 |
Jiro | English | 75 |
Jiro | English | 80 |
Hanako | Math | 88 |
Hanako | Math | 81 |
重複データがあるかどうかは
dupulicated(データ)
で見つけることができます。
1 2 |
duplicated(data) [1] FALSE FALSE TRUE FALSE FALSE FALSE FALSE |
3つ目がTRUEになっているのでこのデータが重複しているということです。
今回のサンプルデータでは3行目の「Taro, Math, 60」のデータですね。
このように重複しているかどうかをTRUE/FALSEで返してくれるので、
sum(duplicated(データ))
とすることで、重複しているレコード数が分かります。
1 2 |
sum(duplicated(data)) [1] 1 |
重複データの対処
すべてが重複しているデータを取り除く
duplicated()で確認した重複データは、全ての項目の値が同じものです。
このような全データが重複しているものを削除するにはdplyrパッケージの
distinct(データ)
を使います。
1 2 3 4 5 6 7 8 9 |
library(dplyr) distinct(data) name subject score 1 Taro English 77 2 Taro Math 60 3 Jiro English 75 4 Jiro English 80 5 Hanako Math 88 6 Hanako Math 81 |
部分的に重複しているデータを取り除く
重複しているデータを扱うとき、すべてが重複しているだけではなく、特定の変数が重複しているものを削除したい場合もあります。
今回の例でいうと、JiroさんのEnglishと、HanakoさんのMathが2行ずつ残っています。
このような場合にもdistinctは使うことができ、
distinct(特定の列, .keep_all=TRUE)
と書きます。
nameとsubjectが重複しているものを削除したい場合のRの書き方は次のようになります。
1 2 3 4 5 6 7 8 9 10 |
data1 <- data %>% distinct(name, subject, .keep_all = TRUE) # 結果の確認 data1 name subject score 1 Taro English 77 2 Taro Math 60 3 Jiro English 75 4 Hanako Math 88 |
JiroさんのEnglishと、HanakoさんのMathが1行ずつになっているのが確認できますね!
最後の「.keep_all」は全変数を残すオプションで、デフォルトではFALSEになっているため、記載しない場合は選択した変数しか残らないようになります。
(今回の例でいうとnameとsubjectしか残らない。)
重複データの平均(または最大値、最小値など)を残す
先ほどの例だと、部分的な重複を削除した時、データフレームの上の行だけが残っています。
例えば、Jiroさんの場合は、もともとのデータでは75点と80点がありましたが、上に位置する75点のみが残りました。
ただ実際には、点数が高い方を残したい、平均点を残したい、など様々な要望があるかと思います。
そのような計算をした上で重複を削除する場合は次のように書きます。(例:平均を残す場合)
データ %>%
group_by(重複変数) %>%
mutate(新しい列 = mean()) %>%
distinct(重複変数, .keep_all=TRUE) %>%
select(-計算に使った変数)
mutateで計算した新しい列を作ったうえで重複を削除するのがポイントです。
大きい値を残す場合はmeanではなくmaxを使うなど、様々な集計に対応できます。
計算に使用した変数(今回のscore)は不要となるため、最後にselectで除外しています。
それでは今回のサンプルデータで、名前と科目が重複した場合は平均点を残すようにしてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
data2 <- data %>% group_by(name, subject) %>% mutate(mean_score = mean(score)) %>% #名前、科目ごとの平均値を計算 distinct(name, subject,.keep_all = TRUE) %>% #重複を削除 select(-score) #重複削除後はもとの列は不要なためマイナスをつける # 結果の確認 data2 # A tibble: 4 × 3 # Groups: name, subject [4] name subject mean_score <chr> <chr> <dbl> 1 Taro English 77 2 Taro Math 60 3 Jiro English 77.5 4 Hanako Math 84.5 |
JiroさんとHanakoさんの重複していたデータが、平均値のみ残った形になっていますね!
重複データを扱う際に参考になれば幸いです!
コメント