【ggplotメモ15】データを扱いやすい形にする

ggplotを使ってグラフを書くには今あるデータの形は扱いづらい!というかできない!という事態が発生することがあるんじゃないかなと思います。今回は、データを処理しやすい形に変える方法を書きます。

例として、あるクラスの英語と数学の試験のデータを作ってみましょう。「rnorm」は正規分布から乱数を生成する関数です。テストの点数には小数点はつかないということで、「round」を使って自然数になるようにしてみました。

id = c( 1:30 )
english = rnorm( 30, mean = 60, sd = 10 )
english = round( english )
math = rnorm( 30, mean = 50, sd = 10 )
math = round( math )
# wide型データ
data = data.frame(
id = id,
english = english,
math = math
)
head( data )
id english math
1 1 58 46
2 2 61 38
3 3 49 55
4 4 62 43
5 5 51 65
6 6 37 47

こんな感じで英語と数学が横に並んでいる(wide型)ものを用意しました。表としては見やすい形ですよね。

で、描きたいグラフはこういうやつです。

library( ggplot2 )
# グラフの基本設定
ggplot() + theme_set( theme_classic(base_size = 12, base_family = "Hiragino Kaku Gothic Pro W3") )
# 描画
b5 <- ggplot( data_long, aes( x = subject, y = score, fill = subject ) ) +
    geom_bar( position = position_dodge( width = .9), stat = "summary", fun = "mean", alpha = .5 ) +
    geom_point( aes( color = subject ), size = .2, shape = 21, stroke = 1 ) +
    stat_summary( fun.data = "mean_se", geom = "errorbar", width = .2) +
    labs(x = "科目", y = "得点" ) +
    scale_y_continuous( limits = c( 0, 100 ) ) +
    theme( legend.position = "none" )
plot( b5 )

横軸が科目、縦軸が得点の棒グラフを描きました。

ggplot( data_long, aes( x = subject, y = score, fill = subject ) )

と書いたように、xの値として指定できるのは1つだけです。なので、wide型では英語と数学に分かれているのを、1つ(上のコードの中の「subject」)にまとめなければいけません。こういうときに使うのが「tidyr」パッケージの「pivot_longer」です。

# long型データ
library( tidyr )
data_long = data %>%
pivot_longer(
  col = -c( "id" ), # まとめないやつ
  names_to = "subject", # まとめた後につける名前
  values_to = "score" # 各列にあったデータにつける名前
)
head( data_long )

こうして出来上がったデータがこちら。

# A tibble: 6 x 3
id subject score
1 1 english 67
2 1 math 50
3 2 english 62
4 2 math 49
5 3 english 59
6 3 math 50

英語と数学が「subject」にまとめられて、その横に各生徒・各科目の点数が並べられるようになりました。こうして、上に示したような棒グラフを描くことができるようになったのでした。このような縦長のデータはlong型と呼ばれます。

wide型からlong型への変換はよくやることだと思うので、ここに置いておきます。それでは、今日はここまで。Enjoy!