Edited at

R初心者はこれを見ろ!便利なパッケージまとめ!入門編③ 相関係数を縦持ちに!


R初心者のデータ加工方法まとめ第三段!

第三回はtidyrgather spreadについてまとめます!

第一回はこちら

 summarise mutate group_byあたりについてまとめてます。

第二回はこちら

 inner_join anti_join %in%あたりについてまとめてます


tidyr::spread

まず、スプレッドからです。

下記のようなデータ(購買データだと思ってください。IDは顧客ID, Weeksは週(1週目~4週目のデータ), Brandは購入した商品のブランド名)を

> table

ID Weeks Brand
1 A 1 ABC
2 A 2 ABC
3 A 3 DEF
4 A 4 ABC
5 B 1 DEF
6 B 2 DEF
7 B 3 DEF
8 B 4 ABC
9 C 1 ABC
10 C 2 GHI
11 C 3 ABC
12 C 4 GHI
13 D 1 GHI
14 D 2 GHI
15 D 3 ABC
16 D 4 DEF

下記のように変形したい!という時に便利です。

Aさん、BさんとそれぞれID別の列にしたい場合ですね。

> table_2

Weeks A B C D
1 1 ABC DEF ABC GHI
2 2 ABC DEF GHI GHI
3 3 DEF DEF ABC ABC
4 4 ABC ABC GHI DEF

こういう場合に、tidyrというパッケージに入っています、spreadが便利です!

使い方は下記のように簡単です。

#これだけです

> table_2 <- table %>%
tidyr::spread(key = ID, value = Brand)
#key = [新しい列にしたい値が入っている列名] 今回はID名を新たな列にしたいので、key = ID
#value = [新たな列の値にしたいものが入っている列名] 今回はBrand名を値としたいので、value = Brand

#以下のように、ID別の列が作成されます。
> table_2
Weeks A B C D
1 1 ABC DEF ABC GHI
2 2 ABC DEF GHI GHI
3 3 DEF DEF ABC ABC
4 4 ABC ABC GHI DEF

これだけです!

使う中で、keyとvalueどっちがどっちだっけ?となった場合は、ぜひこのページを参照ください!


tidyr::gather

gatheはspreadの逆です。

下記のような変形をしたい時に便利です。

#spreadで広げたデータをもとに戻したい!

> table_2
Weeks A B C D
1 1 ABC DEF ABC GHI
2 2 ABC DEF GHI GHI
3 3 DEF DEF ABC ABC
4 4 ABC ABC GHI DEF

> table_3
Weeks ID Brand
1 1 A ABC
2 2 A ABC
3 3 A DEF
4 4 A ABC
5 1 B DEF
6 2 B DEF
7 3 B DEF
8 4 B ABC
9 1 C ABC
10 2 C GHI
11 3 C ABC
12 4 C GHI
13 1 D GHI
14 2 D GHI
15 3 D ABC
16 4 D DEF

spreadの逆でして、列名としていたものを、値として一列に集約したい時に使えます。

使い方は下記の通り、とても簡単。

#元の形を確認

> table_2
Weeks A B C D
1 1 ABC DEF ABC GHI
2 2 ABC DEF GHI GHI
3 3 DEF DEF ABC ABC
4 4 ABC ABC GHI DEF

#table_2を変形
> table_3 <- table_2 %>%
+ tidyr::gather(key = ID, value = Brand, A, B, C, D)

#確認
> table_3
Weeks ID Brand
1 1 A ABC
2 2 A ABC
3 3 A DEF
4 4 A ABC
5 1 B DEF
6 2 B DEF
7 3 B DEF
8 4 B ABC
9 1 C ABC
10 2 C GHI
11 3 C ABC
12 4 C GHI
13 1 D GHI
14 2 D GHI
15 3 D ABC
16 4 D DEF


実用編

例えば、これらの関数を使って相関係数をクロス表から縦持ちにしたりできます。

*データは適当につくったサンプルです!

下記のようなデータがあった場合、

> table
unit price freq temp
1 1 1 4 5
2 5 2 3 2
3 2 3 5 2
4 4 4 2 4
5 2 1 4 5
6 4 2 6 7
7 4 3 4 6
8 3 4 7 2
9 5 1 5 4
10 2 2 6 3
11 4 3 7 6
12 5 4 6 7
13 4 1 5 5
14 2 2 2 4
15 5 3 6 2
16 4 4 4 3

相関係数は関数corを使うと、クロス表でわかりますが、これですとイマイチ使いにくい。
回帰分析で変数間相関が絶対値0.8以上の変数をチェックしたく、また結果を見て閾値を0.7や0.6に変更したいなぁ、という時にこれだとちょっと使い勝手が悪いです。
> cor(table)
unit price freq temp
unit 1.0000000 0.3069703 0.1612065 0.1007272
price 0.3069703 1.0000000 0.1470429 -0.1476601
freq 0.1612065 0.1470429 1.0000000 0.1145931
temp 0.1007272 -0.1476601 0.1145931 1.0000000

そこで、これを縦持ちに変換します。
まず、このクロス表をデータフレームとして、
> df_cor <- cor(table) %>% as.data.frame()

変数名の列を追加します。
> df_cor$Val <- names(table)
> df_cor
unit price freq temp Val
unit 1.0000000 0.3069703 0.1612065 0.1007272 unit
price 0.3069703 1.0000000 0.1470429 -0.1476601 price
freq 0.1612065 0.1470429 1.0000000 0.1145931 freq
temp 0.1007272 -0.1476601 0.1145931 1.0000000 temp

ここでgatherの登場です。
> df_cor <- df_cor %>%
tidyr::gather(key = Val_2, value = Correl, unit, price, freq, temp)

すると、こんな具合に縦持ちになりました。
> df_cor
Val Val_2 Correl
1 unit unit 1.0000000
2 price unit 0.3069703
3 freq unit 0.1612065
4 temp unit 0.1007272
5 unit price 0.3069703
6 price price 1.0000000
7 freq price 0.1470429
8 temp price -0.1476601
9 unit freq 0.1612065
10 price freq 0.1470429
11 freq freq 1.0000000
12 temp freq 0.1145931
13 unit temp 0.1007272
14 price temp -0.1476601
15 freq temp 0.1145931
16 temp temp 1.0000000

同じ変数名の相関は1とわかりきっているので除きます。
> df_cor <- df_cor %>%
dplyr::filter(Correl != 1)

また、同じ変数の組み合わせが2回づつ出てきているので、それも除きます・
> df_cor <- df_cor %>%
distinct(Correl, .keep_all = TRUE)

これで完成です!
> df_cor
Val Val_2 Correl
1 price unit 0.3069703
2 freq unit 0.1612065
3 temp unit 0.1007272
4 freq price 0.1470429
5 temp price -0.1476601
6 temp freq 0.1145931

こういった形で変数間相関を持っておくと、「マルチコを気にして、変数間相関0.8以上をチェックしたけど、0.7以上にしたい!」など閾値を変えた場合でもfilter(Correl >= 0.7)など、対応しやすいです!