趣旨
R使いの皆様は、パネルデータを{plm}
にかけて分析したり、機械学習に突っ込んだりすることがあると思います。
ここで時系列分析をする際、レコードに重複があると{plm}
がエラーを吐き出すことがあります。そのため重複を修正した上で分析にかけなくてはいけません。
そこで、パネルデータの前処理として重複レコードを検索する方法を記しておきます。
Error in pdim.default(index[[1]], index[[2]]) :
duplicate couples (id-time)
In addition: Warning messages:
1: In pdata.frame(data, index) :
duplicate couples (id-time) in resulting pdata.frame
to find out which, use e.g. table(index(your_pdataframe), useNA = "ifany")
2: In is.pbalanced.default(index[[1]], index[[2]]) :
duplicate couples (id-time)
サンプルデータ
個体名と日付のレコードが重複している欠陥のあるデータを用意しておきました。
ここから、「nameとyearのセット」が重複している行を抽出できればOKというわけですね。
df <- data.frame(name = c("sato", "sato", "sato",
"ishii", "ishii", "ishii",
"ohta", "ohta", "ohta"),
year = c(2017, 2018, 2019,
2017, 2017, 2019,
2017, 2018, 2018),
kokugo = c(60, 50, 50,
50, 50, 40,
70, 70, 60))
df
name year kokugo
1 sato 2017 60
2 sato 2018 50
3 sato 2019 50
4 ishii 2017 50
5 ishii 2017 50
6 ishii 2019 40
7 ohta 2017 70
8 ohta 2018 70
9 ohta 2018 60
処理例
レコードの通し番号をつけておく
処理をする前にレコードに番号を振っておくと後で修正するときに楽になります。dplyr::mutate()
を使って、各データに通し番号を付しておきましょう。
library(dplyr)
df2 <- mutate(df, no = row_number())
df2
# A tibble: 9 x 4
name year kokugo no
<fct> <dbl> <dbl> <int>
1 sato 2017 60 1
2 sato 2018 50 2
3 sato 2019 50 3
4 ishii 2017 50 4
5 ishii 2017 50 5
6 ishii 2019 40 6
7 ohta 2017 70 7
8 ohta 2018 70 8
9 ohta 2018 60 9
dplyr::group_by()でグループ化する
{dplyr}
のgroup_by()
関数を使うと、データフレームを変数の値でグループ化できます。これは複数の変数(列)に基づいてグループ化することもできるので、まずはnameとyearでグループ化します。こうすることで、「ある個体のある時点のデータ」という単位で1グループを構成することになります。
df2 <- group_by(.data = df, name, year)
グループ内のデータが2つ以上あるデータを抽出する
理想的には「ある個体のある時点のデータ」、つまり1グループに対して1つのレコードがグループ化されているべきです。ここで、レコードに何かしらの重複があるということは、グループに2つ以上のレコードが記録されていることになります。
そこで、グループ内のレコード数が1より大きいデータをdplyr::filter()
で抽出しましょう。
filter(df2, n() > 1)
# A tibble: 4 x 4
# Groups: name, year [2]
name year kokugo no
<fct> <dbl> <dbl> <int>
1 ishii 2017 50 4
2 ishii 2017 50 5
3 ohta 2018 70 8
4 ohta 2018 60 9
これで問題のあるデータが4, 5, 8, 9行目にあることが判明しました。あとはこれを手作業で修正するなり削除するなりすれば完了です。
これを一行で済ます方法
ちなみに、ここまでの一連の流れをパイプで繋いでしまえばサクッと特定できます。
> df %>% mutate(., no = row_number()) %>% group_by(., name, year) %>% filter(., n() > 1)
# A tibble: 4 x 4
# Groups: name, year [2]
name year kokugo no
<fct> <dbl> <dbl> <int>
1 ishii 2017 50 4
2 ishii 2017 50 5
3 ohta 2018 70 8
4 ohta 2018 60 9
おわりに
よく使うのにすぐ忘れてしまうので書いておきました。
パネルデータをちゃんと処理して気持ちよく分析しましょう。
Enjoy!
おしまい。