R上でデータの可視化(グラフ等を描く)作業を行うためのパッケージとして,ggplot2が広く利用されている.
正直に言えば,可視化作業は,データ分析の中で最も面倒な作業の一つである.このため,データを分析自体はRで行うものの,可視化作業はRで得られた結果をExcel等にコピーして,Excel上で行うのでも構わないと言えば構わない.ただ,結果をExcelのコピーする際にミスをしてしまうことも有りるし,同じ分析方法であっても,対象のデータを変わった場合には,当然ながらまた手作業でイチからグラフを作り直すことになる.さらに,複数人で作業をしている場合などは,それぞれのグラフのデザインが異なって,見栄えが悪くなるといことも起こり得る.
ggplot2を用いれば,Rの出力結果をそのままグラフ化できるので,「コピーの際の手違い」というものは起こり得ないし,データが変わった場合にも,コードを少し変えるだけでグラフを作り直すことができる.さらに,ggplot2を用いることで統一されたデザインポリシーの下でグラフを描くこともできる.
この章では,ggplot2の基本的な使い方を説明する.
ggplot2は美しい描画をしてくれる様々な関数を提供する外部パッケージである.利用するためには,データハンドリングで使ったtidyverse
を読み込む.データハンドリングの時に一度インストールをしているので,今度はスクリプトの冒頭にlibrary(tidyvers)
と書き入れるだけでよい.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
ggplot2自体は「ggplot2」という名前のパッケージであり,インストールするパッケージも本来であれば「ggplot2」パッケージで良いのだが,「tidyverse」パッケージではggplot2を含め様々な便利なパッケージがまとめられている.後々それらのパッケージも利用していきたいので,ここではtidyverseパッケージを利用する.
Step1:データを与えて描画キャンバスを作る
↓
Step2:与えたデータに対して各種の描画命令を与える
↓
Step3:必要ならば凡例や軸の書式の設定をする
↓
Step4:plot()
関数を実行する.
ggplotで処理するデータはロング形式のデータである必要がある. ここでは,前回と同様にirisデータを使うことにする.irisデータは最初からロング形式であるため,そのまま使うことができる. 以下ではirisデータを読み込んで,変数名(列名)を日本語に変更した後,head()関数を用いてデータの冒頭6行分を表示させている.
data_iris <- iris
colnames(data_iris) <- c("がく長","がく幅","花びら長","花びら幅","種類")
head(data_iris)
## がく長 がく幅 花びら長 花びら幅 種類
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
キャンバスの作成にはggplot()
関数を用いる.引数にはデータを与える.
g <- ggplot(data_iris)
これでキャンバスのオブジェクトがg
という名前で格納された.このg
に対して,色々な描画関数を与えていき,最後にg
をplot()
関数で実際に描画させる,というのが基本的な描画のフローとなる.
ちなみに現時点でplot()
を実行すると以下のようになる.
plot(g)
このとおり,まだ中身がなにもないので描画エリアだけの描画となる.
まずはがく長の箱ひげ図を書かせることにしよう.
箱ひげ図を書かせる命令はgeom_boxplot()
関数となる.この関数の第1引数にaes()
関数をあたえる.aes()
関数ではさらにx軸,y軸のデータを設定する.data_irisに含まれている「がく長」の全体のデータを箱ひげ図にしてみよう.データ全体なので,x軸には文字列として”全体”としておく.
g <- ggplot(data_iris) + geom_boxplot(aes(x="全体", y=がく長))
plot(g)
y とxを入れ替えると以下の通りとなる.
g <- ggplot(data_iris) + geom_boxplot(aes(x=がく長, y="全体"))
plot(g)
上記はあくまでがく長全体を一まとめのデータとして扱ったが,例えば,x軸を種類に設定して,種類ごとの箱ひげ図を書かせたいといった場合には以下の通りにする.先ほどと違い種類
にはダブルコーテーションはつかない.これは種類はあくまでdata_irisに含まれる変数名であり,単なる文字列であった"全体"
というのと根本的に異なるものであるためである.
g <- ggplot(data_iris) + geom_boxplot(aes(x=種類, y=がく長))
plot(g)
このように箱ひげ図が種類ごとに描かれる.
箱ひげ図に色を塗りつぶしたい場合には,aes()
にfill
(塗りつぶし)の設定を与える.塗分けは箱ひげ図の場合にはグループ単位で行いたいであろう.そういう場合には,グループ分けに使っている変数,すなわち種類を与えると良い.
g <- ggplot(data_iris) + geom_boxplot(aes(x=種類, y=がく長, fill=種類))
plot(g)
塗りつぶしではなく,枠のみに色を付けたい場合には,fill
の代わりに,color
の設定を与える.
g <- ggplot(data_iris) + geom_boxplot(aes(x=種類, y=がく長, color=種類))
plot(g)
fillとcolorの両方を設定することもできるが,それをすると,枠線と塗りつぶしの色が同じになってしまい,中央値が見えなくなるので,いずれか一方にするべきである.
geom_boxplot()
の第2引数(aes()
関数の外の引数)としてwidthを与える.デフォルトは0.75に設定されてる.
g <- ggplot(data_iris) + geom_boxplot(aes(x=種類, y=がく長, fill=種類),width=0.3 )
plot(g)
g <- ggplot(data_iris) + geom_boxplot(aes(x=種類, y=がく長, fill=種類),width=1.0 )
plot(g)
g <- ggplot(data_iris) + geom_boxplot(aes(x=種類, y=がく長, fill=種類),width=0.75)
plot(g)
今までは「がく長」のみを描画してきたが,「がく幅」や「花びら長」なども同時に描画させたい場合には,以下のようにgeom_boxplotを各変数に対して設ける.x=
で記載されるものはあくまでラベルとなるため,ダブルコーテーション(““)が必要となる.
g <- ggplot(data_iris) +
geom_boxplot(aes(x="がく長",y=がく長))+
geom_boxplot(aes(x="がく幅", y=がく幅))+
geom_boxplot(aes(x="花びら長", y=花びら長))
plot(g)
なお,このようにした場合には,種類ごとに分けることはできなくなる(x軸が変数に対応する形になるので,種類に対応させる軸がなくなる).
塗色をしたい場合には,fill
やcolor
の設定を与える.以下ではfill
を設定している.この例のように,fill
に変数名を設定すると,その変数名に従って色分けされる.
g <- ggplot(data_iris) +
geom_boxplot(aes(x="がく長",y=がく長, fill="がく長"))+
geom_boxplot(aes(x="がく幅", y=がく幅, fill="がく幅"))+
geom_boxplot(aes(x="花びら長", y=花びら長, fill="花びら幅"))
plot(g)
colorを設定した場合.
g <- ggplot(data_iris) +
geom_boxplot(aes(x="がく長",y=がく長, color="がく長"))+
geom_boxplot(aes(x="がく幅", y=がく幅, color="がく幅"))+
geom_boxplot(aes(x="花びら長", y=花びら長, color="花びら幅"))
plot(g)
このデータは,ある地域Aとある地域Bの高校生をランダムに500人ずつ抽出し,それぞれの大学入試共通テストの数学IA,数学IIB,国語をデータ化したものである.このデータを使って,以下の問に答えよ
基本はgeom_point()
である.引数としてaes()
を使ってx,yを設定する.以下は,がく長全体のデータをプロットしたものである.
g <- ggplot(data_iris)+geom_point(aes(x="全体", y=がく長))
plot(g)
つづいて,種類ごとのがく長をプロットした例である.
g <- ggplot(data_iris)+geom_point(aes(x=種類, y=がく長))
plot(g)
全体にしても種類ごとにしても,がく長は0.1刻みで測定されているため,値が同じものが含まれている.上記の設定では,それらは全部重なってしまうため,上記のようなプロットとなる.
geom_point()
だと上記のように同じ値のものが全部重なって1つの点として表記されるため,データ全体がどのように分布しているのかが把握できなくなる.そこで,同じ値のものを水平方向にランダムにバラつかせて描画させるために,
geom_jitter()
を使う.引数はgeom_point()
と同じである.
g <- ggplot(data_iris)+geom_jitter(aes(x=種類, y=がく長))
plot(g)
水平方向にランダムにばらついたことによって,同じ値を取っているものがどれだけあるかがある程度視覚的に把握できるようになる.
もう一度描画させると,先ほどと違うばらつき方になる.
g <- ggplot(data_iris)+geom_jitter(aes(x=種類, y=がく長))
plot(g)
先の例では点をプロットするときに横方向にランダム化させるjitter表示にしていたが,度数分布にすることもできる.
度数分布の場合には,geom_jitter()
の代わりにgeom_dotplot()
関数を用いる.引数がやや多いので以下に表で示す.
引数名 | 内容 |
---|---|
aes(x=, y=) | x軸,y軸の設定 |
binaxis | どちらの軸の変数についての度数分布にするのか |
dotsize | プロットする点のサイズ |
stackdir | どの方向にプロットしていくか.Up(右向き), down(左向き), center(中心ぞろえ)のいずれか |
binwidth | 度数分布における区間幅の設定 |
position | position_nudge() 関数によって描画開始をそれぞれのグループのx軸の中心からどちら向き(正か負か)にどれだけ離すかの設定する.stackdirをcenterにした場合には中心がずれる |
以下に,実際にいくつか例示してみる.なお,1行のソースコードが長くなってきたので,見やすさのため+
で改行しているほか,関数内でも引数単位で適宜改行を入れている.
g <- ggplot(data_iris)+
geom_dotplot(aes(x=種類, y=がく長), binaxis = "y", dotsize = 1.0, stackdir = "down",
binwidth = 0.1, position = position_nudge(-0.025))
plot(g)
g <- ggplot(data_iris)+
geom_dotplot(aes(x=種類, y=がく長), binaxis = "y", dotsize = 0.50, stackdir = "up",
binwidth = 0.1, position = position_nudge(0.025))
plot(g)
g <- ggplot(data_iris)+
geom_dotplot(aes(x=種類, y=がく長), binaxis = "y", dotsize = 0.3, stackdir = "center",
binwidth = 0.3, position = position_nudge(0.225))
plot(g)
以下はbinaxisをxに設定しているためエラーとなる(xはグループ分け変数であり,概念上度数分布というものが存在しないので).
g <- ggplot(data_iris)+
geom_dotplot(aes(x=種類, y=がく長), binaxis = "x", dotsize = 0.3, stackdir = "up",
binwidth = 0.1, position = position_nudge(0.025))
plot(g)
## Warning: The following aesthetics were dropped during statistical transformation: y.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
## the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
## variable into a factor?
## Error in `geom_dotplot()`:
## ! Problem while setting up geom.
## ℹ Error occurred in the 1st layer.
## Caused by error in `compute_geom_1()`:
## ! `geom_dotplot()` requires the following missing aesthetics: y.
箱ひげ図の時と同様に,色や幅を変えることができる.色についてはfill
(塗りつぶし)ではなくcolor
を設定したり,Width
を設定したりして,色や幅を変えることができる.
g <- ggplot(data_iris)+geom_jitter(aes(x=種類, y=がく長, color=種類))
plot(g)
g <- ggplot(data_iris)+geom_jitter(aes(x=種類, y=がく長, color=種類), width = 0.3)
plot(g)
点のプロットと箱ひげ図を重ねることもできる.以下のようにgeom_boxplot()
とgeom_dotplot()
やgeom_jitter()
を+
でつなげればよい.
g<- ggplot(data_iris)+
geom_boxplot(aes(x=種類,y=がく長))+
geom_jitter(aes(x=種類, y=がく長, color=種類))
plot(g)
g<- ggplot(data_iris)+
geom_boxplot(aes(x=種類,y=がく長), width=0.5)+
geom_dotplot(aes(x=種類, y=がく長, color=種類, fill=種類), binaxis = "y",
dotsize = 0.75, stackdir = "down",binwidth = 0.1,
position = position_nudge(-0.025))
plot(g)
aes()
(エステティック)関数の設定項目はx,y軸とfill(塗りつぶし), color(線や点の色設定)が出てきているが,それ以外に以下のようなものがある.
項目 | 内容 |
---|---|
x, y | x軸に設定する変数,y軸に設定する変数 |
color | 点や線の色 |
fill | 面の色 |
alpha | 不透明度 (0が透明,1が不透明) |
size | 点や文字の大きさ,線の太さ |
shape | 点の形 |
linetype | 線の種類 |
group | 反復試行の折れ線グラフなど,色や形はそのままで切り分けたいときに. |
xmin, xmax, ymin, ymax, xend, yend | ものによってつかう. |
極めて多いエラーとして,各geom()
関数を実行していくときに,前の行の末尾に+
を付け忘れたり,最後の行の末尾に+
をつけたりしてしまうことがよくある.
もし,エラーが出てグラフ描画ができなかった場合には,これらのミスをしていないかを確認してみてほしい.
先ほど読み込んだ大学入試共通テストの得点データ(数学IA,数学IIB,国語)を使って以下の問に答えよ.
平均を棒グラフとして,さらに標準偏差や信頼区間をエラーバーとして描く,というケースは非常に多い.そこで以下ではそういう棒グラフの作成方法を説明する.
流れとしては平均と標準偏差の求め,それを元のデータとは別のデータフレームに格納し,そのデータフレームを用いて描画する,という流れとなる.
用いるggplot2の関数はgeom_bar()
とgeom_errorbar()
である.
geom_bar()
は棒グラフを描く関数である.第1引数としてaes()
関数を与え,x軸とy軸を設定する.第2引数にはstat="identity"
を与える.これは「与えたデータをそのまま使う」という意味である.第3引数にはwidthを与える.これは棒の幅を設定する.ただ,第3引数は省略することもできる.
geom_errorbar()
はエラーバーを描く関数である.第1引数としてaes()
関数を与え,x軸,y軸,ymin,ymaxを設定する.x軸,y軸はgeom_bar()
に与えたものと同じもの与える.yminはエラーバーの下限,ymaxはエラーバーの上限を示す.一般的には平均\(\pm\)標準偏差もしくは信頼区間の上限・下限が与えられる.widthはエラーバーの幅を設定する.widthを省略すると,上限・下限を示す水平方向の線分が描かれなくなる.
#データの準備
平均 <- mean(data_iris$がく長)
標準偏差 <- sd(data_iris$がく長)
d <- data.frame( # それぞれ1つずつの値しか格納されていないが,あくまでデータフレームである
平均 = 平均,
標準偏差 = 標準偏差
)
g<-ggplot(d)+
geom_bar(aes(x="全体",y=平均), stat="identity",width = 0.5)+
geom_errorbar(aes(x="全体",y=平均,ymin=平均-標準偏差, ymax=平均+標準偏差),width=0.15)
plot(g)
aggregate()関数グループごとのデータを用意した上で,以下のようにする.
#データの準備
d.mean <- aggregate(がく長~種類,data_iris, mean)
d.sd <- aggregate(がく長~種類,data_iris, sd)
d.mean
## 種類 がく長
## 1 setosa 5.006
## 2 versicolor 5.936
## 3 virginica 6.588
d.sd
## 種類 がく長
## 1 setosa 0.3524897
## 2 versicolor 0.5161711
## 3 virginica 0.6358796
d2 <- data.frame(
種類 = d.mean$種類,
平均 = d.mean$がく長,
標準偏差= d.sd$がく長
)
print(d2)
## 種類 平均 標準偏差
## 1 setosa 5.006 0.3524897
## 2 versicolor 5.936 0.5161711
## 3 virginica 6.588 0.6358796
g <- ggplot(d2)+
geom_bar(aes(x=種類,y=平均,fill=種類),stat="identity")+
geom_errorbar(aes(x=種類,y=平均,ymin=平均-標準偏差, ymax=平均+標準偏差),width=0.15)
plot(g)
さらに,平均値自体を棒グラフに重ねて記述したい場合には以下のようgeom_text()
を用いるる.vjustは,テキストの位置を調整するためのパラメータで,数値が大きいほど下に移動する.負の値にした場合は棒グラフよりも上の表記される.
g <- ggplot(d2)+
geom_bar(aes(x=種類,y=平均,fill=種類),stat="identity")+
geom_errorbar(aes(x=種類,y=平均,ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.15))+
geom_text(aes(x=種類,y=平均,label=round(平均,1)),vjust=5)
plot(g)
今まで,キャンバスを作った際にデータフレームを与え,その後,描画をする際にxとyを指摘してきたが,キャンバスを作るときにxとyも指定することができる.そうすると,描画をするときに,いちいちx,yを指定しなくても良くなる.以下に例を示す.
g <- ggplot(d2)+
geom_bar(aes(x=種類,y=平均,fill=種類),stat="identity")+
geom_errorbar(aes(x=種類,y=平均,ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
geom_text(aes(x=種類,y=平均,label=round(平均,1)),vjust=5)
plot(g)
g <- ggplot(d2,aes(x=種類,y=平均))+
geom_bar(aes(fill=種類),stat="identity")+
geom_errorbar(aes(ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
geom_text(aes(label=round(平均,1)),vjust=5)
plot(g)
データそのものを使って描く場合には以下のようにする. ポイントは以下の通りである.
geom_bar
のstat
をsummary
に設定し,fun.data
に平均と標準偏差を求める関数であるmean_sdl
に設定するか,fun
に平均を求める関数であるmean
を設定することである.geom_errorbar
のstat
を同じくsummary
に設定し,fun.data
に平均と標準偏差を求める関数であるmean_sdl
に設定する.さらにfun.args
にはmean_sdl
関数の引数であるmult
を1
に設定することで,1
倍の標準偏差を算出させる.
mean_sdl
はHmisc
パッケージに含まれているsmean.sdl
という関数を用いて平均と標準偏差を算出してくれる関数である.このsmean_sdl
関数では,第2引数としてmult
という引数があり,これを1
に指定すると1*標準偏差が,2
とすると2*標準偏差が算出されるようになる.もし引数を設定しなかった場合には,デフォルト値をとして2に自動で設定される.mean_sdl
を実施するためにはHmisc
パッケージをインストールしておく必要がある.geom_text
でlabelを与える際にafter_stat()
関数を使って,stat
で求めた値を使うように設定した上で,stat
とfun
をそれぞれsummary
とmean
に設定する.g <- ggplot(data_iris, aes(x=種類,y=がく長,fill=種類))+
geom_bar(stat = "summary", fun.data = "mean_sdl")+ # geom_bar(stat = "summary", fun = "mean") でもよい
geom_errorbar(stat = "summary", fun.data = "mean_sdl", fun.args = list(mult = 1), width=0.15)+
geom_text(aes(label = round(after_stat(y), 2)), stat = "summary", fun = "mean", vjust = -0.5)
plot(g)
なお,上記はエラーバーとして標準偏差を表示させる方法であるが,エラーバーとして標準誤差を使う場合には,もう少しシンプルに書く事が出来る.
g <- ggplot(data_iris, aes(x=種類,y=がく長,fill=種類))+
geom_bar(stat = "summary",fun.data = mean_se)+
geom_errorbar(stat = "summary", fun.data = "mean_se", width=0.15)+
geom_text(aes(label = round(after_stat(y), 2)), stat = "summary", fun = "mean", vjust = -0.5)
plot(g)
geom_bar()に対いて警告が表示されるが,それは"summary"
に指定しているのに明示的にfun
を指定していないため,デフォルトである”mean_se”が適用されていた,ということを示しているだけであるので,気にする必要はない.もし表示を消したければ,fun="mean_se"
を明示的に指定すればよい.
先ほど読み込んだ大学入試共通テストの得点データ(数学IA,数学IIB,国語)を使って以下の問に答えよ.
度数分布表(設定した区間幅のそれぞれに含まれるサンプル数を表にしたもの)をグラフ表示したものをヒストグラムと呼ぶ.ヒストグラムを作成するには
geom_histgram()
を使う
geom_histgram
を使う場合,区間幅はデフォルトではデータの範囲を30等分した値が自動的に設定されるが,binwidth
を設定することによって任意の区間幅に設定することもできる.以下の例では,がく長の値を0.1単位で区切っている.
データを度数分布表やヒストグラムを描く際に,データを区間に分ける処理をbinningと呼ぶ.このため,geom_histgram()
関数で区間幅の引数がbinwidth
となっている.
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく長), binwidth = 0.1)
plot(g)
これだと区間の境界がわかりにくいので,境界を描かせるためには以下のようにする.
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)
plot(g)
種類ごとに分けて分布を作る場合は,aes()の中で
fill`を設定する.
g <- ggplot(data_iris)+
geom_bar(aes(x=がく長, fill=種類),stat="count")
plot(g)
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく長, fill=種類),color="white", binwidth = 0.1)
plot(g)
なお,例えば,がく長が5.7は度数として8となっているが,これは3つの種類をすべて積み上げたものである.すなわち,setosaにおいてがく長5.8なのは2点,Versicolorでは5点,virginicaで1点となっている.
ただ,この場合,重なっている箇所については積み上げグラフになる.
あくまで種類ごとにそれぞれ別々のヒストグラムにしたい,ということであれば,以下のように2つの方法が考えられる.
方法1 データを端からバラバラにして3つのグラフを別々に描く
この場合には,データをfilter()
関数(->参考)を用いて種類ごとに分け,それぞれを描画する.ただし,この場合,coord_cartesian()
関数を使ってx軸の変域を設定しないと,3つのグラフのx軸,y軸の変域がバラバラになってしまう.なので,以下の例のように,coord_cartesian()
を使ってx軸,y軸の変域を設定する.
なお,coord_cartesian()
と類似の働きをするものとしては,xlim()
やylim()
があるが,xlim()
やylim()
はデータそのものからこれらで指定した範囲外のものを除外する(結果として表示も指定範囲に限定される)のに対して,coord_cartesian()
はデータを除外しているわけではなく,単に表示する範囲を指定するだけである.
単に表示を変えたいだけならば,coord_cartesian()
を使うべきである.
g <- ggplot(filter(data_iris,種類=="setosa"))+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)+
#xlim(4,8)+ylim(0,30)
coord_cartesian(xlim = c(4, 8), ylim=c(0,30))
plot(g)
g <- ggplot(filter(data_iris,種類=="versicolor"))+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)+
#xlim(4,8)+ylim(0,30)
coord_cartesian(xlim = c(4, 8), ylim=c(0,30))
plot(g)
g <- ggplot(filter(data_iris,種類=="virginica") )+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)+
#xlim(4,8)+ylim(0,30)
coord_cartesian(xlim = c(4, 8), ylim=c(0,30))
plot(g)
変数の内容を知るための関数としてstr()
という関数がある.実際にこれをfilter()
関数の結果に対してかけてみると,以下の通りとなる.
res<-filter(data_iris,種類=="setosa")
str(res)
## 'data.frame': 50 obs. of 5 variables:
## $ がく長 : num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ がく幅 : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ 花びら長: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ 花びら幅: num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ 種類 : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
データ点数は50点とあり,確かにsetosaのみを取り出せているのがわかる.一方で「種類」列の情報としては,この列は要因型であり,3つの水準(setosa, versicolorだけが表示されているが・・・)で構成されていることが記載されていることがわかる.
方法2:
1つの絵の中で3つに分割して描く(facet_wrap()
の利用)
facet_wrap()
を利用することで1枚のキャンバスを分割して表示させることができる.
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)+
facet_wrap(~種類)
plot(g)
デフォルトでは,横方向(列方向)に分割されていくが,nrow
(行数)を設定することによって縦方向(行方向)にも分割させることができる.
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)+
facet_wrap(~種類,nrow=2)
plot(g)
これまで「がく長」について種類別のヒストグラムを描く方法を説明したが,今度は,複数の変数(例えば,「がく長」と「がく幅」)のヒストグラムを描く方法を説明する.
方法は大きく2つある. 1つは,シンプルに変数ごとに別々のキャンバスを用意して描画する方法である. 以下はその例.
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく長),color="white", binwidth = 0.1)
plot(g)
g <- ggplot(data_iris)+
geom_histogram(aes(x=がく幅),color="white", binwidth = 0.1)
plot(g)
もう1つは,facet_wrap()
を使って1つのキャンバスに複数の変数のヒストグラムを描画する方法である.
この場合は,ggplotに与えるデータをロング形式に変換する必要がある.すなわち,現状では,以下のような表になっているが
種類 | がく長 | がく幅 | 花びら長 | 花びら幅 |
---|---|---|---|---|
setosa | 5.1 | 3.5 | 1.4 | 0.2 |
setosa | 4.9 | 3.0 | 1.4 | 0.2 |
setosa | 4.7 | 3.2 | 1.3 | 0.2 |
… | … | … | … | … |
以下のように変換する必要がある.
種類 | 変数 | 値 |
---|---|---|
setosa | がく長 | 5.1 |
setosa | がく幅 | 3.5 |
setosa | 花びら長 | 1.4 |
setosa | 花びら幅 | 0.2 |
setosa | がく長 | 4.9 |
setosa | がく幅 | 3.0 |
setosa | 花びら長 | 1.4 |
setosa | 花びら幅 | 0.2 |
setosa | がく長 | 4.7 |
setosa | がく幅 | 3.2 |
setosa | 花びら長 | 1.3 |
setosa | 花びら幅 | 0.2 |
… | … | … |
このように変換するためには,データハンドリングで紹介したpivot_longer()
関数を使う.以下のようにする.
data_iris_long <- pivot_longer(data_iris, cols=c(がく長, がく幅, 花びら長, 花びら幅), names_to="変数", values_to="値")
head(data_iris_long)
## # A tibble: 6 × 3
## 種類 変数 値
## <fct> <chr> <dbl>
## 1 setosa がく長 5.1
## 2 setosa がく幅 3.5
## 3 setosa 花びら長 1.4
## 4 setosa 花びら幅 0.2
## 5 setosa がく長 4.9
## 6 setosa がく幅 3
変換が出来たら,filter関数で描画させたい変数のみを抽出したうえで,geom_histgram()
とfacet_wrap()
を使って描画する.
g <- ggplot(filter(data_iris_long,変数=="がく長"|変数=="がく幅"))+
geom_histogram(aes(x=値),color="white", binwidth = 0.1)+
facet_wrap(~変数)
plot(g)
ただ,注意すべき点として,facet_wrap()を使う場合には,x軸の値域は全てのヒストグラムで同じものとなる.このため,上の図のように,明らかに個別の変数のデータとしてはデータが存在しない区間(がく長での4以下の区間や,がく幅での5以上区間)があっても,いずれかの変数でその区間にデータが存在すれば,すべての変数でその区間も含めた形のヒストグラムが描かれることになる.
ヒストグラムを比較することに意味があるなら,そのような表示でも問題はないが,比較するつもりはとくになく,それぞれの変数でヒストグラムを得たいだけならば,無理に1枚のキャンバスに描画しようとせずに,それぞれの変数ごとに別々に描画する方法をとる方がよいだろう.
先ほど読み込んだ大学入試共通テストの得点データ(数学IA,数学IIB,国語)を使って以下の問に答えよ.
2つのデータの関係性を可視化するグラフの代表格は散布図である.散布図は点プロットで紹介したgeom_point()
を用いて以下のようにして描く.
g <- ggplot(data_iris)+
geom_point(aes(x=がく長, y=花びら長))
plot(g)
geom_point()
のaes()
にcolor
を与える.
g <- ggplot(data_iris)+
geom_point(aes(x=がく長, y=花びら長, color=種類))
plot(g)
geom_point()
のaes()
にshape
を与える.
g <- ggplot(data_iris)+
geom_point(aes(x=がく長, y=花びら長, color=種類, shape=種類))
plot(g)
分かりやすく,がく長と花びら長に関係性として,setosaにはほぼ関係性はないが,versicolorとvirginicaにはがく長が長くなると,花びら長も長くなる傾向にあることが分かった.
散布図は回帰分析を行う際の結果の可視化でも改めて触れることにする.
任意の場所に任意の文字や線,図形を書き入れる場合には,annotate()
関数を使う.以下のように,geom_point()
の後にannotate()
を使って,任意の位置に任意の文字を書き入れることができる.以下に代表的な引数を示す.これら以外にも円を描いたり,矢印を描いたりできるので,興味がある人はChatGPTに聞いてみてほしい.
引数名 | 内容 |
---|---|
第1引数 | アノテーションの種類の指定.“text”(テキスト),“segment”(線分),“rect”(四角形)などがある |
x,y | アノテーションを書き入れるx,y座標 |
xend | 線を引く場合の終点のx座標 |
yend | 線を引く場合の終点のy座標 |
xmin, xmax, ymin, ymax | 四角形を描く場合の座標 |
label | 書き入れる文字列 |
color | 文字の色,線の色 |
fill | 四角形の塗りつぶしの色 |
size | 文字の大きさ |
angle | 文字の角度 |
linewidth | 線の幅 |
g <- ggplot(data_iris)+
geom_point(aes(x=がく長, y=花びら長, color=種類, shape=種類))+
annotate("text", x=5, y=2, label="ここに文字を書き入れる",color="orange",size=7, angle=39)+
annotate("segment", x=4, y=2, xend=6, yend=3, linewidth=1.5)+
annotate("rect", xmin=5, xmax=6, ymin=4, ymax=6,color="red",fill="blue")
plot(g)
先ほど読み込んだ大学入試共通テストの得点データ(数学IA,数学IIB,国語)を使って以下の問に答えよ.
segment
を用いて,数学の平均点を示すY軸に平行な線分と国語の平均点を示すx軸に並行な線分を引け.text
を用いて,「第1象限」から「第4象限」までを,それぞれ該当する象限の中の任意の位置に記述せよ.デフォルトでは軸タイトルはaes()
で設定した各軸の変数名がそのまま入るが,xlab
やylab
を使って自分の好きなように変えることができる.
引数にNULL
を設定すると軸タイトルを消せる.
以下では,x軸のタイトルを消し,y軸のタイトルを「がく長」に書き換えている.
g <- ggplot(d2,aes(x=種類,y=平均))+
geom_bar(aes(fill=種類),stat="identity")+
geom_errorbar(aes(ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
xlab(NULL)+ylab("がく長")
plot(g)
labs()
を使う.
引数には,aes()
で色を指定するときに使った引数に,書き換えたいタイトルを与える.
以下の例では,fill
を使って色を与えているので,fill=****
というのを引数としてlabelに与える.
g <- ggplot(d2,aes(x=種類,y=平均))+
geom_bar(aes(fill=種類),stat="identity")+
geom_errorbar(aes(ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
xlab(NULL)+ylab("学長")+labs(fill="種類")
plot(g)
ちなみにlabsは引数として以下のものを取る.
項目 | 内容 |
---|---|
title | タイトル |
subtitle | サブタイトル |
x | x軸ラベル |
y | y軸ラベル |
caption | キャプション |
fill またはcolor | 凡例ラベルのタイトル |
この通りに,xlabやylabもlabsでまとめて設定することもできる.
g <- ggplot(d2,aes(x=種類,y=平均))+
geom_bar(aes(fill=種類),stat="identity")+
geom_errorbar(aes(ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
labs(x=NULL, y="がく長", fill="種類")
plot(g)
theme(legend.position = "none")
を使う.
g <- ggplot(d2,aes(x=種類,y=平均))+
geom_bar(aes(fill=種類),stat="identity")+
geom_errorbar(aes(ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
xlab(NULL)+ylab("がく長")+
theme(legend.position = "none")
plot(g)
凡例を消した時と同じようにthemeを使う.引数には以下のようなものを入れる.
axis.text.x=element_text(size=15)
axis.text.y=element_text(size=15)
axis.title.x=element_text(size=15)
axis.title.y=element_text(size=15)
legend.text=element_text(size=9)
g <- ggplot(d2,aes(x=種類,y=平均))+
geom_bar(aes(fill=種類),stat="identity")+
geom_errorbar(aes(ymin=平均-標準偏差, ymax=平均+標準偏差,width=0.3))+
xlab("種類")+ylab("花弁の幅")+
theme(legend.position = 'none')+
theme(
axis.title.x=element_text(size=15),
axis.title.y=element_text(size=15),
axis.text.x=element_text(size=10),
axis.text.y=element_text(size=10),
legend.text=element_text(size=5),
legend.title = element_text(size=8) )
plot(g)
themeは細かくいろいろ設定できる.設定できるものは以下の通り.
名前 | 説明 | 要素の型 |
---|---|---|
text | すべてのテキスト要素 | element_text() |
axis.title | 両軸ラベルの体裁 | element_text() |
axis.title.x | x軸ラベルの体裁 | element_text() |
axis.title.y | y軸ラベルの体裁 | element_text() |
axis.text | 両軸目盛ラベルの体裁 | element_text() |
axis.text.x | x軸目盛ラベルの体裁 | element_text() |
axis.text.y | y軸目盛ラベルの体裁 | element_text() |
legend.text | 凡例項目の体裁 | element_text() |
legend.title | 凡例タイトルの体裁 | element_text() |
plot.title | タイトルの体裁 | element_text() |
strip.text | 両方向ファセットラベルテキストの体裁 | element_text() |
strip.text.x | 水平方向ファセットラベルテキストの体裁 | element_text() |
strip.text.y | 垂直方向ファセットラベルテキストの体裁 | element_text() |
legend.position | 凡例の位置 | left, right, bottom, top, c(x,y) :x,yは0~1 |
legend.background | 凡例の背景 | element_rect(fill=“xxx”, color=“yyy”) fillは塗りつぶし,colorは枠線 |
plot.background | プロット全体の背景 | element_rect(fill=“xxx”, color=“yyy”) |
panel.background | プロット領域の背景 | element_rect() |
panel.border | プロット領域の枠線 | element_rect(linetype=“xxx”) |
rect | 全ての長方形要素 | element_rect() |
panel.grid.major | 主目盛線 | element_line() |
panel.grid.major.x | 主目盛線の垂直方向 | element_line() |
panel.grid.major.y | 主目盛線の水平方向 | element_line() |
panel.grid.minor | 補助目盛線 | element_line() |
panel.grid.minor.x | 補助目盛線の垂直方向 | element_line() |
panel.grid.minor.y | 補助目盛線の水平方向 | element_line() |
axis.line | 軸に沿った線 | element_line() |
line | すべての線要素 | element_line() |
設定項目 | element_text()の引数 |
---|---|
角度 | angle |
水平位置 | hjust(0:左揃え~1:右揃え) |
垂直位置 | vjust(0:下揃え~1:上揃え) |
サイズ | size |
色 | color |
スタイル | face(bold or italic) |
フォントファミリー | family |
element_rect(fill, color, size, linetype, inherit.blank)
— 長方形
項目 | 内容 |
---|---|
fill | 塗りつぶしの色 |
color | 枠の色 |
element_line(color, size, linetype, lineend, arrow, inherit.blank)
—
線
element_blank()
— 空 消したい要素にはこれを指定する
すでにこちらで説明したとおり,グラフの表示範囲を限定したい場合には,coord_cartesian()
を使う.代表的な引数は以下の2つである.
目盛ラベルを変えるには,scale_x_****
やscale_y_***
を使う.
以下は,x軸の目盛りをsetosa, versicolor, virgnicaから,a, b,
cに変え,y軸を普通の目盛から対数目盛に変えた例である.
g <- ggplot(data_iris)+
geom_bar(aes(x=種類,fill=種類),stat="count") +
scale_x_discrete(labels=c("a","b","c"))+
scale_y_log10(limits=c(1,1000))
plot(g)
***
の部分には,いずれも以下のものが入る.
*** | 内容 |
---|---|
discrete | 離散目盛 |
continuous | 連続目盛 |
log10 | 対数目盛 |
reverse | 目盛の逆転 |
sqrt | 平方根目盛 |
また,代表的な引数としては以下のものが入る.
引数 | 内容 |
---|---|
labels | 離散目盛のラベルを変える(以下のbreaksを併用すると,連続変数でも可能) |
breaks | 連続変数の目盛のうち指定したものだけを表示させる |
limits | 連続変数の表示範囲を指定したものにする.xlim,ylimと同じ効果. |
name | 変数の軸ラベルを変える.xlab,ylabと同じ効果. |
ちなみに,xlim
やylim
は内部ではscale_x_continuous(limits=...)
やscale_y_continuous(limits=)
を使っている.このため,これらはデータそのものを除外しており,結果として表示範囲も変わるという仕組みになっている.単に表示範囲を変えたいだけであれば,coord_cartesian()
を使う方がよい.
結局,軸タイトルを変える方法って,色々あるということである. xlabでもよいし,labs(x=)dでもよいし,scale_x_***(name=)でも変えれる.
グループ分けにfillを使っている場合は,sacle_fill_dicrete()
を,Colorを使っている場合はscale_color_discrete()
を使う.
g <- ggplot(data_iris)+
geom_bar(aes(x=種類,fill=種類),stat="count")+
scale_fill_discrete(label=c("花1","花2","花3"))
plot(g)
ggplot2で描画するときにエラーが出るケースとして,行末の「+」の付け忘れや消し忘れがある.もし思い通りにグラフが描画されない場合には,この点を確認してみるとよい.
ggplot2で色の指定をする際に設定できる色のリストは以下の通りである.
これら以外の色でもrgb
関数を使って,赤,緑,青の光の3原色の比率を指定することで,任意の色を指定することもできる.第1引数が赤の強さ,第2引数が緑の強さ,第3引数が青の強さを示す.なお,rgb
関数に与える数値は,0から1の数値にしている必要があるが,一般に色の階調は0~255の数字で表記されるため,以下の例のように,R,G,Bそれぞれに対応した数値を255で割っておく必要がある.例えば,赤と青の強さを255にして,緑の強さを0にすると,赤と青の混合色である紫色が得られる.
color = rgb(255/255, 255/255, 0/255) #紫色になる
その他,色の16進数コードを指定することもできる.
ggplot2を使った描画はRでの様々な統計分析の結果をそのまま可視化できるので,描画の際に誤りが少なくなるため便利である上,デザインを統一するのも容易である. ただ,細かく設定できる分,設定項目が多く,正直私自身も覚えきれていない. なので,ggplot2を使った描画では都度ネットで「ggplot2 棒グラフ」や「ggplot2 ヒストグラム」などという形で検索を掛けて,自分が描画したいグラフに近いものをコピペして,それを少しずつ変えていくという方法が有効である.あるいは,ChatGPTにCSVファイルを添付したうえで「ggplot2で添付のCSVファイルを箱ひげ図にしてください」といった形で質問をすると,その都度コードを生成してくれるので,それを参考にするのもよいだろう.
重要なことは,自分で0から書くのはできなくても,人が書いたコードを読んで,何をしているかを理解できる能力を持っていることである.それが出来ていれば,ネットから見つけられるコードをコピペしてカスタマイズして自分が欲しい図を書かせることができるようになる.