1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【R】 パネルデータから重複レコードを見つける

Last updated at Posted at 2020-02-25

趣旨

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!

おしまい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?