R初心者のデータ加工方法まとめ第三段!
第三回はtidyr
のgather
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)
など、対応しやすいです!