いずにゃんの研究日記

専門性を広げるための練習場

はじめてのtidyr(1):データをwideからlongにする,その逆も

サンプルデータは下記記事を参照。

izunyan.hatenablog.com

        name grade height  B  W  H
1   高海千歌     2    157 82 59 83
2   桜内梨子     2    160 80 58 82
3   松浦果南     3    162 83 58 84
4 黒澤ダイヤ     3    162 80 57 80
5     渡辺曜     2    157 82 57 81
6   津島善子     1    156 79 58 80
7 国木田花丸     1    152 83 57 83
8   小原鞠莉     3    163 87 60 84
9 黒澤ルビィ     1    154 76 56 79

このように,1行に1人のデータが入っているのがよく見るデータの形であるが,解析によっては1人のデータを数行にわたらせるときがある。たとえば,複数の測定時点の変数がt1, t2, t3…と変数としてあり,それをtimeという1つの変数にまとめて縦に値を表示させたいといった場合などである。

ここではあまりあてはまらないかもしれないが,強引に身長とスリーサイズを1つの変数で表したいとする。

つまり,横長(wide)データを縦長(long)データに変換する。そんなときに便利なのがtidyrパッケージである。チートシートでは,"Reshaping Data"の部分に出てくる。

tidyrが入っていない人は,ネットにつながった環境で以下を実行

install.packages("tidyr")

まずはtidyrを読み込む。なお,%>%演算子を使うので,dplyrも読み込む。

library(tidyr)
library(dplyr)


wideからlongへの変換

wideからlongへの変換はgather( )で行う。 新しい変数bodyにheight, B, W, Hという変数名が値として入り,同じく新しい変数valueに先ほどの変数名の対応するデータが入るという構造である。nameとgradeには-をつけたが,これは変換せずそのまま残す際の記号である。

dat_long <- dat %>% gather(body,value,-name,-grade)
dat_long

次のようなデータ構造に変換された。

         name grade   body value
1    高海千歌     2 height   157
2    桜内梨子     2 height   160
3    松浦果南     3 height   162
4  黒澤ダイヤ     3 height   162
5      渡辺曜     2 height   157
6    津島善子     1 height   156
7  国木田花丸     1 height   152
8    小原鞠莉     3 height   163
9  黒澤ルビィ     1 height   154
10   高海千歌     2      B    82
11   桜内梨子     2      B    80
12   松浦果南     3      B    83
13 黒澤ダイヤ     3      B    80
14     渡辺曜     2      B    82
15   津島善子     1      B    79
16 国木田花丸     1      B    83
17   小原鞠莉     3      B    87
18 黒澤ルビィ     1      B    76
19   高海千歌     2      W    59
20   桜内梨子     2      W    58
21   松浦果南     3      W    58
22 黒澤ダイヤ     3      W    57
23     渡辺曜     2      W    57
24   津島善子     1      W    58
25 国木田花丸     1      W    57
26   小原鞠莉     3      W    60
27 黒澤ルビィ     1      W    56
28   高海千歌     2      H    83
29   桜内梨子     2      H    82
30   松浦果南     3      H    84
31 黒澤ダイヤ     3      H    80
32     渡辺曜     2      H    81
33   津島善子     1      H    80
34 国木田花丸     1      H    83
35   小原鞠莉     3      H    84
36 黒澤ルビィ     1      H    79

分かりにくいので,名前でソートしてみる。

dat_long %>% arrange(name)
         name grade   body value
1    高海千歌     2 height   157
2    高海千歌     2      B    82
3    高海千歌     2      W    59
4    高海千歌     2      H    83
5  国木田花丸     1 height   152
6  国木田花丸     1      B    83
7  国木田花丸     1      W    57
8  国木田花丸     1      H    83
9  黒澤ダイヤ     3 height   162
10 黒澤ダイヤ     3      B    80
11 黒澤ダイヤ     3      W    57
12 黒澤ダイヤ     3      H    80
13 黒澤ルビィ     1 height   154
14 黒澤ルビィ     1      B    76
15 黒澤ルビィ     1      W    56
16 黒澤ルビィ     1      H    79
17   桜内梨子     2 height   160
18   桜内梨子     2      B    80
19   桜内梨子     2      W    58
20   桜内梨子     2      H    82
21   小原鞠莉     3 height   163
22   小原鞠莉     3      B    87
23   小原鞠莉     3      W    60
24   小原鞠莉     3      H    84
25   松浦果南     3 height   162
26   松浦果南     3      B    83
27   松浦果南     3      W    58
28   松浦果南     3      H    84
29   津島善子     1 height   156
30   津島善子     1      B    79
31   津島善子     1      W    58
32   津島善子     1      H    80
33     渡辺曜     2 height   157
34     渡辺曜     2      B    82
35     渡辺曜     2      W    57
36     渡辺曜     2      H    81

このように,1名につき4行のlongなデータ構造に変換された。 つまり,9名×4で36行のデータとなった。


longからwideへの変換

これを逆にlongからwideに変換したいときはspread( )を使う。横長に並べなおす部分の変数だけ( )内に並べる

dat_long %>% spread(body,value) 

これでlongからwideに変換された。つまり元に戻った。

        name grade height  B  W  H
1   高海千歌     2    157 82 59 83
2   桜内梨子     2    160 80 58 82
3   松浦果南     3    162 83 58 84
4 黒澤ダイヤ     3    162 80 57 80
5     渡辺曜     2    157 82 57 81
6   津島善子     1    156 79 58 80
7 国木田花丸     1    152 83 57 83
8   小原鞠莉     3    163 87 60 84
9 黒澤ルビィ     1    154 76 56 79