Rによるデータ分析

Rのggplot2

ggplot2は、 R で美しいグラフを簡単に描くことができるソフトです。 グラフィカル分析 にも適しています。 現在は、Python版もあるようです。

共通のコード

使用例は下記になります。 gglplot2というパッケージをあらかじめインストールしておきます。

下記は、コピーペーストで、そのまま使えます。 この例では、Cドライブの「Rtest」というフォルダに、 「Data.csv」という名前でデータが入っている事を想定しています。

「ggplot」から始まる命令文の前に、下記は必ず必要です。

library(ggplot2) # パッケージの読み込み
setwd("C:/Rtest") # 作業用ディレクトリを変更
Data <- read.csv("Data.csv", header=T) # データを読み込み

知りたいグラフへの近道

2つの量的変数の関係を詳しく調べるためのグラフ
折れ線グラフ
層別の折れ線グラフ
等間隔の折れ線グラフ
層別の散布図
回帰線
言葉の散布図

ヒストグラム
基本のヒストグラム
層別のヒストグラム
区切りの良い区間のヒストグラム

1つの量的変数の分析のためのグラフ
1つの量的変数を1つの質的変数で分解するグラフ
1つの量的変数を2つの質的変数で分解するグラフ
1つの量的変数を3つの質的変数で分解するグラフ

棒グラフ
普通の棒グラフ
層別の棒グラフ
頻度グラフ

グラフの調整
ラベルの向きを変える

2つの量的変数の関係を詳しく調べるためのグラフ

変化のグラフ には 折れ線グラフ があります。

折れ線グラフ

共通のコード の後の入力になります。

ggplot2の 折れ線グラフ は、「 散布図 のデータを線でつないだもの」になっています。 一般的な折れ線グラフは、X軸のデータは等間隔に並ぶもの、と思いますが、 ggplot2の場合、デフォルトでは等間隔に並ぶようになっていません。

データは、「X1」という列名で横軸にするもの、「Y1」という列名で数値が入っていることを想定しています。

ggplot(Data, aes(x=X1,y=Y1, group=1)) + geom_line() + geom_point()# 折れ線グラフを描く
折れ線グラフ

最後のgeom_point()を入れないと、プロットが取れて、線だけになります。

層別の折れ線グラフ

データは、「X1」という列名で横軸にするもの、「Y1」、「Y2」、「Y3」、という列名で数値が入っていることを想定しています。 Xが共通で、Yが複数あるような場合に、ひとつのグラフで表したいことがあります。 この場合は、Yをつなげて、ひとつの列にして、列の違いを表す変数を作ると、グラフにできます。 つがなげるためには、tidyrというパッケージのインストールが必要です。

なお、下記のプログラムでは、ひとつの列にする時に「X1の列以外をつなげる」という指示の出し方をしています。 XでもYでもない列があると、その列もYとして積み上げられてしまいます。

なお、下記コードは、別の変数になっているYをひとつの変数に統合するためのやり方が入っています。 始めから、統合されたデータがある場合は、 こんなにややこしくなりません。
折れ線グラフのデータ

library(ggplot2) # パッケージの読み込み
setwd("C:/Rtest") # 作業用ディレクトリを変更
Data <- read.csv("Data.csv", header=T) # データを読み込み
library(tidyr) # パッケージの読み込み
Data_long <- tidyr::gather(Data, key="Yno", value = Ys, -X1) # 縦型に変換(X1の列以外を積み上げる)
ggplot(Data_long, aes(x=X1,y=Ys, colour=Yno)) + geom_line() + geom_point()# 層別の折れ線グラフを描く
層別の折れ線グラフ

グラフを分けたい時は、facetを使います。 「nrow=1000」というのは、「縦に1000個の枠を作る」という指示で、カテゴリの数よりも多ければ1000でなくても良いです。 また、グラフを分けると、色を分けなくてもカテゴリが区別できるので、下記では色分けを外しています。 色分けを外すと、凡例が出て来ないのでグラフがすっきりしますし、PCの動きも軽くなります。 ちなみに、色で区別されていると、グラフを見る人は、色とカテゴリの関係を頭の中で対応付ける必要があり、グラフで伝えたいことを理解してもらいにくくします。 そのため、色は、使わないで済むなら使わない方が良いです。
ggplot(Data_long, aes(x=X1,y=Ys)) + geom_line() + geom_point() + facet_wrap(~Yno,nrow=1000)# 枠を分けて折れ線グラフを描く

層別の折れ線グラフ

グラフ毎に分けたい時というのは、カテゴリ毎のYの高さの違いではなく、カテゴリ毎のデータの変動の仕方を見たい時になります。 こういう時は、グラフの縦軸の範囲は、グラフ毎に変わった方が良いです。 グラフ毎に、カテゴリ毎の最大値・最小値に合わせて縦軸の範囲が決まっていると、それぞれのカテゴリの変化の仕方が見やすくなります。
ggplot(Data_long, aes(x=X1,y=Ys)) + geom_line() + geom_point() + facet_wrap(~Yno,scales="free",nrow=1000)# Yの範囲の異なる折れ線グラフを描く

層別の折れ線グラフ

カテゴリ毎に縦軸の範囲を変える技は、カテゴリ毎に単位や桁数がまったく異なる場合には、もっと効果がはっきりします。 下の3つのグラフは、上記とは異なるデータについて、3つの層別グラフを作ったものです。
一番右の場合は、 Y1は正の数で、Y2は負の数ですが、まったく同じ動きをしていることがわかります。 また、Y4は、データのある期間毎に、「1から0」という動きをしていることもわかります。
単位や桁数が異なる折れ線グラフを複数作ることは、他のソフトでもできますが、 プロット領域の横の長さがそろわないことがよく起きます。 この技だと、きちんとそろうので、グラフの比較がやりやすいです。
層別の折れ線グラフ 層別の折れ線グラフ 層別の折れ線グラフ

グラフの数が多い場合は、「nrows=1000」を外して、縦横の数をソフトにお任せにした方が良いこともあります。 ちなみに、縦軸がグラフ毎に異なる折れ線グラフは、 Excelのスパークライン の方が、手軽に使えます。
ggplot(Data_long, aes(x=X1,y=Ys)) + geom_line() + geom_point() + facet_wrap(~Yno,scales="free")# Yの範囲の異なる折れ線グラフを大量に描く

層別の折れ線グラフ

等間隔の折れ線グラフ

X1が数値型のデータで、等間隔ではないので、グラフも等間隔ではないです。 等間隔ではない数値型データでも等間隔にしたい場合や、文字列型の場合、グラフが1本の場合は、
Data$X1 <-factor(Data$X1) # X1を文字列型にする
ggplot(Data, aes(x=X1,y=Y1, group=1)) + geom_line() + geom_point()#データはひとつのグループであることを指定して、グラフにする
とすればできます。
折れ線グラフ

または、X1のデータを行番号に入れ替えてしまうと、等間隔の数値データになります。
Data$X1 <-as.numeric(row.names(Data)) # X1を行番号にする
ggplot(Data, aes(x=X1,y=Y1)) + geom_line() + geom_point()#グラフにする
とすればできます。
折れ線グラフ

層別の2次元散布図 色分け・形分け

データは、「C1」という列名でカテゴリがあり、「X1」、「Y1」という列名で数値が入っていることを想定しています。
データの読み込みまでは、上記と同じです。

ggplot(Data, aes(x=X1, y=Y1)) + geom_point(aes(colour=C1, shape=C1))# 二次元散布図 色分け・形分け
二次元散布図 色分け

色分けや形分けの片方だけにするには、最後のカッコからいらないものを消します。 色分けや形分けをしない場合は、最後のカッコが空になります。
ggplot(Data, aes(x=X1, y=Y1)) + geom_point())# 二次元散布図

範囲の調整

X軸とY軸の範囲について、デフォルトでは、すべてのデータが含まれるようなちょうど良い大きさに自動で決まります。 外れ値等も含め、データ全体を眺めておきたい時には、便利です。

他のグラフと範囲を合わせたり、等、範囲を指定したい場合は変えることができます。 ここでは、X軸とY軸の両方とも0と20の範囲にした例になります。

ggplot(Data, aes(x=X1, y=Y1)) + geom_point(aes(colour=C1, shape=C1)) + coord_cartesian(xlim=c(0,20),ylim=c(0,20)) # 軸の範囲を調整する
二次元散布図 範囲の調整

回帰線

カテゴリ毎に回帰直線を入れることができます。 線形混合モデル のデータをグラフにしたい時に便利です。

ggplot(Data, aes(x=X1, y=Y1)) + geom_point(aes(colour=C1, shape=C1)) + geom_smooth(method = "lm",aes(fill = C1)) # 回帰直線を入れる
二次元散布図 回帰直線

最後の「aes(fill = C1)」がないと、カテゴリ毎ではなく、全データの回帰直線になります。

言葉の散布図

言葉の散布図 を作ることもできます。

ggplot(Data, aes(x=X1, y=Y1,label=C1)) + geom_text() # 言葉の散布図
言葉の散布図 言葉の散布図

上の図では、同じ値のデータが重なっています。 こういう場合に、少し散らす方法もあります。 実行するたびに、乱数が発生して、配置は毎回微妙に変わります。 0.2のところを大きくすると、散らばり方が大きくなります。
ggplot(Data, aes(x=X1, y=Y1,label=C1)) + geom_text(position=position_jitter(0.2)) # 言葉ジター散布図
言葉の散布図

ヒストグラム

ヒストグラム の作り方です。 共通のコード の後の入力になります。

ヒストグラムは、 1つの量的変数の分析のためのグラフ の仲間ですが、グラフの作り方が少し違うので分けました。

基本のヒストグラム

データは、「Y1」という列名で数値が入っていることを想定しています。

ggplot(Data, aes(x=Y1)) + geom_histogram() # ヒストグラムを描く
ヒストグラム2

層別のヒストグラム

層別のヒストグラムも作れます。 データは、「C1」という列名でカテゴリ、「Y1」という列名で数値が入っていることを想定しています。

ggplot(Data, aes(x=Y1)) + geom_histogram() + facet_grid(C1~.)# 層別ヒストグラムを描く
層別ヒストグラム

さらに層別するヒストグラムも作れます。 データは、「C1」、「C2」という列名でカテゴリ、「Y1」という列名で数値が入っていることを想定しています。

ggplot(Data, aes(x=Y1)) + geom_histogram() + facet_grid(C1+C2~.)# 2段層別ヒストグラムを描く
2段層別ヒストグラム

区切りの良い区間のヒストグラム

ggplotのデフォルトでは、データの範囲が30区間に分けられて、ヒストグラムが作られるようになっています。
ヒストグラム

10,20,30のような区切りの良い区間にするには、データ自体を10刻みにして、 区間の幅を10に設定するとできます。
(※ ここでは切り捨ての関数のtruncを使っていますが、扱う現象によっては、四捨五入や切り上げの関数を使った方が良いこともあるかと思います。)

Data[,'Y1r']<-trunc(Data[,'Y1']/10)*10 # 1の桁以下を切り捨てて10刻みにする
ggplot(Data, aes(x=Y1r)) + geom_histogram(binwidth = 10) # ヒストグラムを描く
ヒストグラム

このグラフの見方ですが、ちょうど「10」の目盛りの上にある棒は、「10以上、20未満」のデータの数を表します。

刻みの幅は、好みで変えられます。 trunc関数を使う時にかけたり割ったりする数字と、binwidthの数字を同じにするのがポイントです。

Data[,'Y1r']<-trunc(Data[,'Y1']) # 1刻みにする
Data[,'Y1r']<-trunc(Data[,'Y1']/0.5)*0.5 # 0.5刻みにする


ちなみに、区切りの良いヒストグラムは、ヒストグラムの機能を使わずに 頻度グラフ の機能を使っても作れます。 他のソフトの棒グラフの機能では、こんなに簡単にヒストグラムを作れないのですが、 ggplot2の場合、横軸するデータが量的変数になっていると、棒グラフの横軸が量的変数になるため、こんな事ができてしまいます。

Data[,'Y1r']<-trunc(Data[,'Y1']/10)*10 # 1の桁以下を切り捨てて10刻みにする
ggplot(Data, aes(x=Y1r)) + geom_bar() # ヒストグラムを描く
ヒストグラム

1つの量的変数の分析のためのグラフ

1つの量的変数を1つの質的変数で分解するグラフ

1次元散布図 の作り方です。

ggplot(Data, aes(x=C1, y=Y1)) + geom_point() # 一次元散布図を描く
1次元散布図

最後の行を変えると、 ジター散布図になります。 プロットの大きさはsize、横方向の散らばり具合はposition=position_jitterの数字で調節できます。

ggplot(Data, aes(x=C1, y=Y1)) + geom_jitter(size=1, position=position_jitter(0.1))# 一次元ジター散布図を描く
1次元散布図

箱ひげ図 の作り方です。

ggplot(Data, aes(x=C1, y=Y1)) + geom_boxplot() # 箱ひげ図を描く
箱ひげ図

1つの量的変数を2つの質的変数で分解するグラフ

「C2」という列名でもうひとつカテゴリあった場合、そのカテゴリでも分けることができます。 二元配置分散分析 のデータに向いています。

ggplot(Data, aes(x=C1, y=Y1)) + geom_jitter(size=1, position=position_jitter(0.1)) +facet_grid(.~C2)# 一次元散布図(二元配置)を描く
1次元散布図

ここでカテゴリが多い場合の例として、こんなものがあったとします。
1次元散布図

上記では、facet_gridを使っていますが、これを使うと、無理にでも横一列に並びます。 facet_wrapを使うと、グラフの縦方向にも分割して、バランスよく並べてくれます。

ggplot(Data, aes(x=C2, y=Y1)) + geom_point() +facet_wrap(~C1)# 一次元散布図をたくさん並べる。
1次元散布図

1つの量的変数を3つの質的変数で分解するグラフ

さらに「C3」という列名でもうひとつカテゴリあった場合、そのカテゴリでも分けることができます。

ggplot(Data, aes(x=C1, y=Y1)) + geom_jitter(size=1, position=position_jitter(0.1)) +facet_grid(.~C2+C3)# 一次元散布図(三元配置)を描く
1次元散布図

グラフの並べ方の縦横を、「C2」と「C3」にすることもできます。

ggplot(Data, aes(x=C1, y=Y1)) + geom_jitter(size=1, position=position_jitter(0.1)) +facet_grid(C2~C3)# 一次元散布図(三元配置)を描く
1次元散布図

ggplot2では、facet_gridやfacet_wrapで、4つ以上の質的変数があっても対応できます。 使う機会はないかもしれませんが、 seaborn では、枠は縦横に1変数ずつを設定するところまでなので、その点は、ggplot2の方が自由度が高いです。

棒グラフ

普通の棒グラフ

棒グラフ の作り方です。 共通のコード の後の入力になります。

データは、「C1」という列名でカテゴリ、「Y1」という列名で数値が入っていることを想定しています。 基本的に一次元散布図と同じです。

ggplot(Data, aes(x=C1, y=Y1)) + geom_bar(stat = "identity") # 棒グラフを描く
棒グラフ

層別の棒グラフ

カテゴリが2つあって、かつ、色分けもしたい場合です。

データは、「C1」、「C2」という列名でカテゴリ、「Y1」という列名で数値が入っていることを想定しています。

ggplot(Data, aes(x=C1, y=Y1)) + geom_bar(stat="identity", aes(fill=C1)) + facet_grid(. ~ C2) # 層別の棒グラフを描く
棒グラフ

頻度グラフ

データは、「C1」、「C2」という質的変数が入っていることを想定しています。 ggplot2の棒グラフのデフォルトは頻度の集計グラフになっています。

ggplot(Data, aes(x=C1)) + geom_bar() + facet_grid(. ~ C2)# 頻度グラフを描く
棒グラフ 棒グラフのデータ

頻度グラフの時ですが、xが量的変数の場合でも、同じ数字であればカウントします。 このサイトでは、 ヒストグラムの調整 でこの機能を使っています。 量的変数の桁をうまく丸めると、実務に使いやすいヒストグラムが作れます。

グラフの調整

ラベルの向きを変える

カテゴリが長い時は、ラベルの向きを変えると良いです。

ggplot(Data, aes(x=C1, y=Y1)) + geom_bar(stat = "identity") + theme(axis.text = element_text(angle = 90)) # Xラベルの向きが変わった棒グラフを描く
棒グラフ

ggplot(Data, aes(x=C1, y=Y1)) + geom_boxplot() + theme(axis.text = element_text(angle = 90)) # Xラベルの向きが変わった箱ひげ図を描く
箱ひげ図



参考文献

ggplot2の解説は数え切れないほどあります。

チートシート https://rstudio.com/wp-content/uploads/2016/10/ggplot2-cheatsheet-2.0-ja.pdf
とてもコンパクトにまとまっています。 筆者の場合は、「こんなグラフは作れるかな?」というのは、これで見つけてます。 その後で、検索してます。





Rによるデータ分析

データサイエンス教室