読者です 読者をやめる 読者になる 読者になる

Mukku John Blog

取り組んでいること を つらつら と

ggplot2を使って、折れ線グラフを作る-1

R グラフィックス クックブック 7回目

ggplot2パッケージを利用して、折れ線グラフを作成していきます。
この3つを対象にします。

  • 折れ線グラフ
  • 点をもつ折れ線グラフ
  • 複数の線の折れ線グラフ

折れ線グラフ

データはこちらを使います。
R: Biochemical Oxygen Demand

> BOD
  Time demand
1    1    8.3
2    2   10.3
3    3   19.0
4    4   16.0
5    5   15.6
6    7   19.8

> str(BOD)
'data.frame':	6 obs. of  2 variables:
 $ Time  : num  1 2 3 4 5 7
 $ demand: num  8.3 10.3 19 16 15.6 19.8
 - attr(*, "reference")= chr "A1.4, p. 270"


x軸にTime列を、y軸にdemand列をマッピングし、折れ線グラフで図示します。

ggplot(BOD, aes(x=Time,y=demand)) + geom_line()

f:id:MukkuJohn:20160822204002p:plain


Time=6に該当するデータが存在しないのに、図示されています。
Time列が、数値型で連続値と捉えれられているためです。

$ Time  : num  1 2 3 4 5 7


離散値にすれば、データセットに含まれないデータは図示されません。
離散値とするためには、ファクタを使います。

#BODデータセットを変更しないように、別オブジェクトに格納する
BOD_1 <- BOD 
#Time列の値をファクタに変換する
BOD_1$Time <- factor(BOD_1$Time)


ファクタに変換することで、データ毎にラベルづけが行われます。

 $ Time  : Factor w/ 6 levels "1","2","3","4",..: 1 2 3 4 5 6


Time列をファクタに変換したBOD_1データセットを、折れ線グラフに図示します。

#group引数でdemandデータが同じグループに属していることを示す
ggplot(BOD_1, aes(x=Time,y=demand, group=1)) + geom_line()

f:id:MukkuJohn:20160822204552p:plain

折れ線グラフのy軸は、
マッピングされたデータの最小値~最大値を含むように調整されます。

y軸の表示範囲は、0始まりにした方が良い場合もあります。
そのためには、下記の2つがあります。

  • ylim()で範囲を指定する
  • expand_limits()で任意の値を含む様に指定する

変更点の違いだけを明確にするために、重複部分を変数に取ります。

bodLineChart <-
  ggplot(BOD_1, aes(x=Time,y=demand, group=1)) + 
  geom_line()
ylim()で範囲を指定する

y軸の表示最小値~表示最大値を指定します。

bodLineChart + ylim(0, max(BOD_1$demand))

f:id:MukkuJohn:20160822210115p:plain

expand_limits()で任意の値を含む様に指定する

グラフに表示する値を指定します。

bodLineChart + expand_limits(y=5)

f:id:MukkuJohn:20160822210248p:plain

ちなみに、下記の2つのコマンドは同じグラフになります。
expand_limitsの表示最大値は、データの最大値を取ります。

bodLineChart + ylim(0, max(BOD_1$demand))
bodLineChart + expand_limits(y=0)

点をもつ折れ線グラフ

y軸にマッピングされたデータの図示部分に、点を追加します。こんな図です。
(データは、BOD_1データセットを使っています。)
f:id:MukkuJohn:20160822210612p:plain

上のグラフのコードはこちらです。(拍子抜け・・・)

ggplot(BOD_1, aes(x=Time,y=demand, group=1)) + 
  geom_line() +
  geom_point()

geom_point()が追加されただけですね。


この点を追加した折れ線グラフですが、
x軸に対して、データが等間隔に存在しない場合に有効です。
(下記グラフ、大昔は推定値みたいです。そんな頻繁には要らないデータです。)
f:id:MukkuJohn:20160822211328p:plain
余談ですが、y軸を対数表示にすると、近代の人口増加が伸びすぎな事が分かります。
f:id:MukkuJohn:20160822211551p:plain

複数の線の折れ線グラフ

データはこちらを使います。
R: The Effect of Vitamin C on Tooth Growth in Guinea Pigs

> head(ToothGrowth)
   len supp dose
1  4.2   VC  0.5
2 11.5   VC  0.5
3  7.3   VC  0.5
4  5.8   VC  0.5
5  6.4   VC  0.5
6 10.0   VC  0.5

> str(ToothGrowth)
'data.frame':	60 obs. of  3 variables:
 $ len : num  4.2 11.5 7.3 5.8 6.4 10 11.2 11.2 5.2 7 ...
 $ supp: Factor w/ 2 levels "OJ","VC": 2 2 2 2 2 2 2 2 2 2 ...
 $ dose: num  0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...

dose列をx軸にとり、supp列の値でグループ化された、lenの平均値を
折れ線グラフに図示したいと思います。

データの加工にplyrパッケージを利用します。(最近、個人的に大活躍)
CRAN - Package plyr

library(plyr)
tg <- ddply(ToothGrowth, c("supp","dose"), summarise, length=mean(len))


加工したデータは、こちらです。

> tg
  supp dose length
1   OJ  0.5  13.23
2   OJ  1.0  22.70
3   OJ  2.0  26.06
4   VC  0.5   7.98
5   VC  1.0  16.77
6   VC  2.0  26.14

> str(tg)
'data.frame':	6 obs. of  3 variables:
 $ supp  : Factor w/ 2 levels "OJ","VC": 1 1 1 2 2 2
 $ dose  : num  0.5 1 2 0.5 1 2
 $ length: num  13.23 22.7 26.06 7.98 16.77 ...


複数の線を図示するには、colourかlinetypeに離散値のグループを指定します。

  • colourに指定した場合
ggplot(tg, aes(x=dose,y=length,colour=supp)) + geom_line()

supp値が色で分かれて図示されています。
f:id:MukkuJohn:20160822212918p:plain

  • linetypeに指定した場合
ggplot(tg, aes(x=dose,y=length,linetype=supp)) + geom_line()

supp値が線の種類で(実線と破線)分かれて図示されています。
f:id:MukkuJohn:20160822213129p:plain


この記事の最初のグラフでも触れた様に、dose列が数値型であり、
連続値として扱われているため、データに存在しない1.5がグラフに表れています。
そのため、ファクタに変換し、離散値として扱います。

ggplot(tg, aes(x=factor(dose),y=length,colour=supp, group=supp)) + 
  geom_line()

f:id:MukkuJohn:20160822213558p:plain
(x軸で、1.5の列が消えました。)


わざわざsupp列で集約したのに、groupを指定しないとどうなるのか?

#groupを指定しないで、図示してみる
ggplot(tg,aes(x=dose,y=length)) + geom_line()

こんなギザギザのグラフになります。
f:id:MukkuJohn:20160822213833p:plain
それぞれのdose値で、2点のデータが図示されています。
groupが指定されないと、どの値でグループ化するのか分からないためです。

ギザギザが出てきたら、何かしら漏れている感じでしょうね。


複数の折れ線グラフにも、点を表示することができます。

ggplot(tg, aes(x=dose,y=length,shape=supp)) + 
  geom_line() + 
  geom_point(size=4)

f:id:MukkuJohn:20160822214846p:plain

ggplot(tg, aes(x=dose,y=length,fill=supp)) + 
  geom_line() + 
  geom_point(size=4,shape=23)

f:id:MukkuJohn:20160822214935p:plain

複数の折れ線グラフに点を表示する時は、groupの指定の代わりに、
shapefillを指定します。後は、勝手にグループ化してくれます。

上のグラフは、x軸=2.0で、OJグループとVCグループの値が重なっています。
(データがそうなのだからしょうがないと思うけど・・・)
過去記事でも散々触れてきた、position_dodgeでずらすことができます。
(データがそうなのだから、ずらす必要はないと思うんだけど・・・)

こんな感じです。

ggplot(tg, aes(x=dose,y=length,shape=supp)) + 
  geom_line(position = position_dodge(0.2)) + 
  geom_point(position = position_dodge(0.2), size=4)

f:id:MukkuJohn:20160822215539p:plain



次回は、線や点の体裁を変更したり、網掛け領域付きにしてみます。