準備

まず、今回使うパッケージを読み込む。インストール済みでないものは、install.packages() を使ってまずインストールする。

インストールしていないパッケージがある場合。

インストール済んだら、読み込む。

分析結果を図表にする。

例として、 淺野・矢内 (2013, 2019刊行予定)で使われている衆議院総選挙の小選挙区候補者データセット hr96-17.Rds. を利用する。フォイルをダウンロードし、プロジェクト内の data フォルダ(他の場所がよければ自分で指定せよ)に保存しよう。

このデータセットはR特有のRds形式のファイルに保存されている。Rdsファイルは、readr::read_rds() で読み込むことができる。

## # A tibble: 6 x 22
##   party party_code  year ku      kun name  status previous    wl voteshare
##   <chr>      <int> <int> <chr> <int> <chr>  <int>    <int> <int>     <dbl>
## 1 LDP            1  1996 aichi     6 ITO,…      0        0     0      26.1
## 2 LDP            1  1996 aichi     7 NIWA…      0        0     0      25.9
## 3 LDP            1  1996 aichi     9 YOSH…      0        0     0      24.8
## 4 LDP            1  1996 aichi    10 MORI…      0        0     0      30.2
## 5 LDP            1  1996 aomo…     4 TSUS…      0        0     0      36.6
## 6 LDP            1  1996 chiba     3 MATS…      0        0     0      34.5
## # ... with 12 more variables: age <int>, nocand <int>, rank <int>,
## #   vote <int>, eligible <int>, turnout <dbl>, exp <int>, expm <dbl>,
## #   vs <dbl>, exppv <dbl>, smd <dbl>, party_jpn <chr>
## # A tibble: 6 x 22
##   party party_code  year ku      kun name  status previous    wl voteshare
##   <chr>      <int> <int> <chr> <int> <chr>  <int>    <int> <int>     <dbl>
## 1 DPJ            3  2009 osaka     8 NAKA…      2       11     1      53.3
## 2 DPJ            3  2009 yama…     1 KANO…      2       11     1      46.2
## 3 SDP            9  2000 gunma     5 YAMA…      2       11     0      16.7
## 4 LP            18  2000 naga…     1 NISH…      2       11     0      27.9
## 5 inde…         99  2003 yama…     3 KATO…      2       11     1      58.9
## 6 LDP            1  2012 kago…     1 YASU…      2       12     1      45.5
## # ... with 12 more variables: age <int>, nocand <int>, rank <int>,
## #   vote <int>, eligible <int>, turnout <dbl>, exp <int>, expm <dbl>,
## #   vs <dbl>, exppv <dbl>, smd <dbl>, party_jpn <chr>
## Observations: 8,803
## Variables: 22
## $ party      <chr> "LDP", "LDP", "LDP", "LDP", "LDP", "LDP", "LDP", "L...
## $ party_code <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
## $ year       <int> 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 199...
## $ ku         <chr> "aichi", "aichi", "aichi", "aichi", "aomori", "chib...
## $ kun        <int> 6, 7, 9, 10, 4, 3, 9, 3, 1, 6, 11, 2, 1, 2, 3, 4, 7...
## $ name       <chr> "ITO, KATSUNDO", "NIWA, TAICHI", "YOSHIKAWA, HIROSH...
## $ status     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ previous   <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ wl         <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ voteshare  <dbl> 26.1, 25.9, 24.8, 30.2, 36.6, 34.5, 34.5, 34.2, 35....
## $ age        <int> 51, 49, 73, 50, 42, 34, 30, 40, 45, 55, 28, 47, 50,...
## $ nocand     <int> 8, 7, 7, 7, 3, 5, 4, 4, 4, 3, 4, 4, 4, 5, 5, 4, 4, ...
## $ rank       <int> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, ...
## $ vote       <int> 59631, 49727, 58059, 72178, 70590, 73254, 75667, 48...
## $ eligible   <int> 433930, 357984, 393953, 437148, 317873, 392771, 397...
## $ turnout    <dbl> 54.2, 55.5, 60.6, 56.0, 61.9, 55.4, 57.0, 69.4, 51....
## $ exp        <int> 10987232, 14030115, 4711892, 9513777, 12128399, NA,...
## $ expm       <dbl> 10.987232, 14.030115, 4.711892, 9.513777, 12.128399...
## $ vs         <dbl> 0.261, 0.259, 0.248, 0.302, 0.366, 0.345, 0.345, 0....
## $ exppv      <dbl> 25.32029, 39.19202, 11.96054, 21.76329, 38.15486, N...
## $ smd        <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ party_jpn  <chr> "自民党", "自民党", "自民党", "自民党", "自民党", "自民党", "自民党", "自...

これで、データセットがRに読み込まれた。HRという名前がこのデータフレームオブジェクトを参照している。

このデータセットは、複数の選挙結果を含んでいる。 どの年の選挙が含まれているか確認してみよう。 table() 関数で簡単な表ができる。 データフレームの中にあるそれぞれの変数にアクセスするために、with() 関数を一緒に使う。

## year
## 1996 2000 2003 2005 2009 2012 2014 2017 
## 1261 1199 1026  989 1139 1294  959  936

8つの選挙に関するデータがあることがわかる。 2009年のデータだけ取り出して練習に使おう。 特定の条件を満たす観測値だけを取り出すには、 dplyr::filter() が使える。

## year
## 2009 
## 1139

ここでパイプ %>% はパイプの左側で評価された結果をパイプの右側に送り、右側の関数は受け取ったものを第1引数として利用する。したがって、HR09 %>% filter (year == 2009) の実行結果はfilter(HR09, year == 2009) と全く同じである。 つまり、この例ではパイプを使う必要はまったくない。 しかし、将来的にはパイプを多用することになるので、簡単な例を使ってしっかり使い方を身につけよう。パイプを複数回使えば、複雑な変換を簡単に行うことが可能になる。パイプは、magrittr パッケージに含まれているが、dplyr を読み込むと自動的にmagrittrも読み込まれる。また、tidyverseを読み込むと、dplyr も読み込まれる。したがって、いつもtidyverse を読み込んでおいたほうが楽だ。

以下では、2009年の衆院選の結果だけが含まれた HR09 を使って図表の作り方を学ぶ。

Rで表を作る

2009年の衆院選データを使い、候補者の立場(status, 現職か元職か新人か)と選挙の勝敗 (wl) のクロス表を作る。

##       wl
## status   0   1   2
##      0 559  80  43
##      1 169 175  52
##      2  14  45   2

このままではどの数字がどのカテゴリを表しているかわかりにくいので、変数にラベルをつけよう。 ラベルをつけるために、変数の種類を整数 (integer) から因子 (factor) に変える。 二つの変数、wlstatusにラベルをつけよう。 後で使うかもしれないので、全体のデータ(2009年以外を含む)にラベルをつけ、2009年の分を改めて取り出そう。

先ほどと同じクロス表をもう一度作る。

##       結果
## 立場 落選 当選 復活当選
##   新人  559   80       43
##   現職  169  175       52
##   元職   14   45        2

データの内容を理解するためには、この表で十分かもしれない。 しかし、この表をそのまま論文(または課題)にコピペして使ってはいけない。 論文等で使うには、表の見た目を整える必要がある。

そこですぐに思いつくのは、MS Excel やLibreOffice Calc などに数字を入力して表を作る方法だろう。 しかし、表計算ソフトに数字を手動で入力して表を作るのはやめたほうが良い。理由は2つある。第1に、入力ミスをする可能性がある。第2に、これがより重要だが、手入力は面倒(時間の無駄)である。 幸い、Rには見栄えのよい表を作るための関数があるので、それを利用する。

xtablestargazer を使ってLaTeX 用の表を作る

xtable

xtable::xtable() を使えば、RでLaTeX用の表を簡単に作ることができる。 LaTeX の使い方はこの授業では解説しないが、研究者を目指すなら使うべきである。 理由は、論文を書くのが楽になるからである。 LaTeXを使うことによって論文執筆が楽になる場面はたくさんあるが、表をRで作れるというのは楽できる場面の1つである。 計量分析を用いた論文では図表をたくさん使うので、 賢明な皆さん(特に研究で計量分析を使う皆さん)は、MS Word とお別れしましょう。

LaTeX がどんなものか知りたいなら、まず『LaTeX 2\(\epsilon\) 美文書作成入門』を読むことをすすめる。

LaTeX の表を作るには、表オブジェクトを xtable()に渡せばよい。 (行列または回帰分析の結果もそのまま渡せる。 詳しくは、methods(xtable) を実行されたい。)

## % latex table generated in R 3.5.0 by xtable 1.8-2 package
## % Fri Sep 21 16:14:43 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{lccc}
##   \hline
##  & 落選 & 当選 & 復活当選 \\ 
##   \hline
## 新人 & 559 &  80 &  43 \\ 
##   現職 & 169 & 175 &  52 \\ 
##   元職 &  14 &  45 &   2 \\ 
##    \hline
## \end{tabular}
## \caption{候補者の立場と選挙結果} 
## \label{tbl:status-result}
## \end{table}

この結果をコピペしてもよいが、次のようにtex ファイルに保存することもできる。

表を微調整したいときは、保存したファイルを編集すればよい。

表は、LaTeX の代わりにHTML ように出力することもでできる。そのためには、type = ‘html’ とする。

候補者の立場と選挙結果
落選 当選 復活当選
新人 559 80 43
現職 169 175 52
元職 14 45 2


R Markdown でHTML 出力するときは、この方法で表を作り、チャンクオプションでresults='asis'と指定する。

より詳しい使い方は、 The xtable gallery (by Jonathan Swinton) を参照されたい。


knitr::kable()

Rマークダウンを使って文章を作るさいは、knitr::kable() を使うこともできる。使い方は簡単で、以下のようにする。

候補者の立場と選挙結果
落選 当選 復活当選
新人 559 80 43
現職 169 175 52
元職 14 45 2

stargazer

回帰分析の結果を表にまとめるときは、stargazer::stargazer() が便利である(感じの悪い名前だが、便利なので我慢して使う。あるいは皮肉なのか?)。 例のために、実際には何の役にも立たない回帰直線を推定し、表を作ってみよう。(回帰分析は4日目の内容なので、現時点では理解できなくてもいいが、後で復習すること。)

## 
## % Table created by stargazer v.5.2.2 by Marek Hlavac, Harvard University. E-mail: hlavac at fas.harvard.edu
## % Date and time: Fri, Sep 21, 2018 - 16:14:43
## % Requires LaTeX packages: dcolumn 
## \begin{table}[!htbp] \centering 
##   \caption{Results of Linear Regressions} 
##   \label{tbl:reg-res} 
## \begin{tabular}{@{\extracolsep{5pt}}lD{.}{.}{-2} D{.}{.}{-2} D{.}{.}{-2} } 
## \\[-1.8ex]\hline 
## \hline \\[-1.8ex] 
##  & \multicolumn{3}{c}{Outcome variable} \\ 
## \cline{2-4} 
## \\[-1.8ex] & \multicolumn{3}{c}{Vote share (%)} \\ 
## \\[-1.8ex] & \multicolumn{1}{c}{(1)} & \multicolumn{1}{c}{(2)} & \multicolumn{1}{c}{(3)}\\ 
## \hline \\[-1.8ex] 
##  expenditure (million yen) & 3.07 &  & 2.14 \\ 
##   & (0.10) &  & (0.11) \\ 
##   & & & \\ 
##  number of wins &  & 5.35 & 2.79 \\ 
##   &  & (0.19) & (0.22) \\ 
##   & & & \\ 
##  constant & 7.74 & 16.85 & 8.42 \\ 
##   & (0.76) & (0.61) & (0.71) \\ 
##   & & & \\ 
## \hline \\[-1.8ex] 
## Observations & \multicolumn{1}{c}{1,124} & \multicolumn{1}{c}{1,139} & \multicolumn{1}{c}{1,124} \\ 
## Adjusted R$^{2}$ & \multicolumn{1}{c}{0.48} & \multicolumn{1}{c}{0.40} & \multicolumn{1}{c}{0.54} \\ 
## F Statistic & \multicolumn{1}{c}{1,028.24} & \multicolumn{1}{c}{768.21} & \multicolumn{1}{c}{672.30} \\ 
## \hline 
## \hline \\[-1.8ex] 
## \end{tabular} 
## \end{table}

LaTeX の表がコンソールに表示されるとともに、“stargazer-reg-res.tex” と言う名前のファイルに保存された。 ファイルが保存されたのは、out 引数でファイル名を指定したからである。

stargazer()を使うときは、star.cutoffs = NAomit.table.layout = “n” の指定を忘れずに。これを忘れると、ものすごく迷惑な星印が表についてしまう。私たちは政治学者(社会科学者)であって、天文学者ではないことをお忘れなく!

HTML 用の表は、type = “html” で得られる(type のデフォルトは ‘latex’ である)。 (R Markdown でHTML 出力するときは、チャンクオプションでresults=‘asis’ に。)

Results of Linear Regressions
Outcome variable
Vote share (%)
(1) (2) (3)
expenditure (million yen) 3.07 2.14
(0.10) (0.11)
number of wins 5.35 2.79
(0.19) (0.22)
constant 7.74 16.85 8.42
(0.76) (0.61) (0.71)
Observations 1,124 1,139 1,124
Adjusted R2 0.48 0.40 0.54
F Statistic 1,028.24 768.21 672.30


より詳しい使い方は、 A Stargazer Cheatsheet を参照されたい。


表を CSV ファイルに保存する

LaTeX をどうしても使いたくない場合、(まず、5,000回考え直し、それでもなお使いたくないなら)表をCSVファイルに保存し、それをExcel やCalc などで開いて編集することもできる。 表をCSV ファイルに保存するには、write.csv() を使う。

現在の作業ディレクトリに、“tbl-st-wl.csv” という名前のファイルが保存されているはずである。 これをExcel 等で開いて表を整形すれば、数値を手入力する手間は省ける。


ggplot2 で図を作る

論文やプレゼンテーションで使う図は、ggplot2 を使って作る。 ggplot2 を使えば、Rで美しい図を作ることができる。 言うまでもなく、研究は見た目よりも中身(図が伝えるメッセージ)の方が大切である。 しかし、保持する情報が同じなら、美しい図の方が汚い図よりも望ましい。 汚い図を解読するより、美しい図を愉しむ方が多くの読者にとって楽である。 したがって、美しい図の方が、読者に情報を正しく伝達する可能性が高いと考えられる。 美しい図は、ggplot2 を使わなくてもできる。しかし、ggplot2 を使わずに美しい図を作るには、熟練Rユーザになる必要がる。ggplot2 を使えば、ある程度美しい(少なくとも読むに耐える)図がデフォルトでできる。 つまり、ggplot2 は美しい図を作るための必要条件ではないが、(ほぼ)十分条件である(ただし、統計の使い方を正しく理解していることを前提とする)。

ggplot2は(も) Hadley Wickham (日本の一部のRユーザは、「羽鳥先生」と呼んで崇拝している)によって開発された。

使い方は、ココ に載っている。 より詳しい使い方は、Hadley Wickham. (2016). ggplot2: Elegant Graphics for Data Analysis, 2nd ed. (Springer) (ココ で入手できる)を参照されたい。

ggplot2 入門

ggplot2 で図を作るときはいつも ggplot2::ggplot() 関数を使う。

ggplot() の第1引数には、データフレームを渡す。 したがって、ggplot2で図を作るためには、必要な変数を1つのデータフレームに保存する必要がある。

第2引数では、aesaestheticsの略)を指定する(より正確には、mapping = aes(…)である)。 視覚化したい変数をaesで指定する。 例えば、2次元の図(散布図など)を作るときには、 横軸 \(x\) と縦軸 \(y\) の変数を指定する。 さらに、色 (color)、大きさ (size) などを指定して、図で表現する次元を増やすことができる。

次に、ggplot()で作られたオブジェクトに、グラフィックの層 (layer) を加える。 異なる種類の図は、異なる種類の層 (layer) で作る。 例えば、散布図を作りたいときは、geom_point() 層を加える。 ヒストグラムには geom_histogram()を使う。 これらの例が示すように、グラフィック層は geomgeometry の略)から始まる。 1つの図に複数のグラフィック層を重ねることもできる。

最後に、図に必要な他の要素、例えば、軸ラベルや凡例を加える(ただし、凡例は通常は自動的にできる)。

例として、選挙費用 (exp) と過去の当選回数 (previous) の散布図を作ってみよう。 まず、ggplot()関数でggplotオブジェクトを作る。 次に、geom_point()で散布図用の層 (layer) を加える。 最後に、labs() で軸ラベルとタイトルをつける(論文で使う図を作るときは、タイトルを空欄にして、図のに番号つきのキャプションをつける。)

これで散布図ができた。表示以外のステップは、1度に実行することもできる。

図を表示するときには、print()を使うが、これを使わずに単に scatter1 としても通常は図が表示される。 しかし、安全のため、常にprint()を使ったほうが良い(R Markdownを使う場合は特に)。

次に、選挙費用のヒストグラムを作ってみよう。 通常のヒストグラムは1つの変数を図にするので、aes では x のみ指定すればよい。

このヒストグラムの縦軸は、「数(count; frequency, 頻度)」である。 縦軸を確率密度にしたいときは、次のようにする。

このように、aesy = ..density..をしてすればよい。 “density” の前後についているドットは、この “density” がデータフレームにもともとあった変数ではなく、ggplot() によって計算され、ggplot 内に保存されているものであることを示している。

ヒストグラムの一つひとつの棒(bin と呼ばれる)の幅を指定することもできる。200万円ごとに一つのビンにまとめたければ、次のようにする。

次に、選挙費用の箱ひげ図を、過去の当選回数別に作って並べてみよう。

ここでは、 previous 変数を aes で指定するとき、as.factor() を使っている。 こうすることで、ggplotに previous がカテゴリー変数(したがって、箱ひげ図をグループ化できる)ことを伝えている。

続いて、得票率と選挙費用の散布図を作り、その上に回帰直線を重ね書きしてみよう。 回帰直線は、geom_smooth(method = 'lm') で描ける。

geom_smooth() はデフォルトで95%信頼区間を直線の周りに示す。 他の信頼度を使いたいときは、level を指定する。 例えば、50%信頼区間に変えるには次のようにする。

信頼区間を示したくないときは、se = FALSE とする。

ggplotで日本語を使う

通常の図で日本語を表示できるようにしただけでは、(Mac の)ggplot2で日本語を使うことはできない。 試しに、簡単な図を作ってみると、

のように、ggplotで作った図では日本語が表示されない。

ggplot2で日本語を使う場合、ggplotのテーマで日本語を表示できるフォンとを選ぶ必要がある。 Macでヒラギノ角ゴシックを使うには、以下のようにテーマを設定する(もちろん、他に好みのフォントがあれば、違うフォントを選んでも良い)。**Windowsの場合は特に何もしなくてよい(はず)。

フォントに、10ポイントのヒラギノゴシックを指定する。

先ほどの図を表示してみよう。

これでうまくいかないときは以下を試す。

これで日本語が表示できるようになった。



ggplot で作った図を保存する

図を画像ファイル (PNG file) に保存する

ggplotで作った図は、 ggplot2::ggsave() で保存できる。 例えば、

で、scatter1 がfigs フォルダの中に ‘scatter-eg1.pn’ として保存される。 plot を指定しないと、最後に作った図が保存される。

図を保存するときは、実際に図として使う図の幅と高さを指定する。 幅 (width) が 6インチで 高さ (height) が 4.5インチ の図は、A4用紙を縦に置いた場合にはおおよそ半ページを占める。

図をPDFファイルとして保存する。

LaTeX 用に図を保存するときは、PDF で保存したほうがよい。 Macでは、quartz()type = “pdf” を指定すればPDFができる。

quartz() で新しいグラフィックデバイスを開き、そこにprint()で図を載せ、最後に dev.off()でデバイスを閉じている。 デバイスを閉じるのを忘れると、後で作った図もすべてこのデバイスに載ってしまうので、デバイスを閉じ忘れないように注意が必要である。 また、quartz()を使った図の保存はRマークダウンファイル上だとうまくいかないことがあるので、この部分はチャンクオプションで eval=FALSE を指定し、実行するときはコマンドをConsoleにコピー&ペースとした方がよい。

Windowsでは、(おそらく) ggsave() でPDFができる。

これでうまくいかないときは、pdf() を次のように使う。

ほんの少しだけ高度な使い方

グループごとにプロットの色やサイズ、形を変える

グループごとに色分け(サイズ分け、形分け)した図を作るには、aes でcolor (size, shape) にグループを表すカテゴリ変数を渡せばよい。 凡例は自動的にできる。

例として、議員が民主党 (DPJ) に所属していたかどうかで色分けしてみよう。 まず、民主党所属を表すダミー変数を作る。

このダミー変数を使い、得票率と選挙費用の散布図を、民主党議員かどうかによって色分けして作ってみよう。

カテゴリ変数で色分けされた凡例を調整したいときは、scale_color_discrete(). さらに、guides() で凡例の表示順を変えることができる。

同じように、点の大きさを過去の当選回数によって変えてみよう。変数 previous を連続変数として扱うと、凡例は scale_size_continuous() で調整できる。

グループごとに作った図を並べる:Facetting

グループごとに分けて作った図を並べるときは、facetting (面刻み) という方法を使う ggplot2 には、2種類のfacetting が用意されている。 行グループと列グループによって並べる(グループ変数が2種類ある、または特定の方向に向かって並べたい)ときは、facet_grid()を使い、1つのグループ変数しか使わな(かつ、並べる方向は気にしない)ときはfacet_wrap()を使う。

まず、facet_grid()の使い方を説明する。 例として、民主党に所属するかどうかでグループ分けをした選挙費用のヒストグラムを作る。 Facetting は facet_grid(row_factor ~ column_factor) で行う。 ここでは、列要素のみを指定する(つまり、図を横に並べる)。

縦に並べたいなら、次のようにする。

二つのグループ変数(カテゴリ変数)を使って図をグリッド上に並べることもできる。 例えば、

のように並べられる。

グループごとに図を作る範囲を変えるには、scale = “free” とする(横軸のみ可変にするには scale = “free_x”、縦軸のみ可変にするには scale = “free_y” とする)。

次に、 facet_wrap()の使い方を説明する。 この関数はグループ片数が1つだが、グループの数が多いために1行(あるいは1列)だけでは図を並べきれないときに便利である。 例として、選挙費用のヒストグラムを過去の当選回数別に作って並べてみよう。


表から図へ

クロス表をモザイク図にする

候補者の立場(現職、元職、新人)と選挙結果をもう1度クロス表にしてみよう。

##           立場
## 結果     新人 現職 元職
##   落選      559  169   14
##   当選       80  175   45
##   復活当選   43   52    2

この情報をより直感的(あるいは視覚的)に伝えるために、表の情報をモザイク図にする。 まず、ggplot2 を使えるようにするため、データフレームを作る。 その際、望んた形のデータフームを作るために、tidyr::gather() を使う。

# total num. of candidates by status
tbl_st <- with(HR09, table(status))
# turn the table into a matrix
tbl_st_wl2 <- as.matrix(tbl_st_wl2[1:3, 1:3])
tbl_st <- as.matrix(tbl_st[1:3])
# Create a data frame
# make variables of the share of each status and
# of the share of each result for each status
df <- data_frame(status = levels(HR09$status),
                 status_pct = 100 * as.vector(tbl_st / sum(tbl_st)),
                 win = 100 * as.vector(tbl_st_wl2[2,] / tbl_st),
                 zombie = 100 * as.vector(tbl_st_wl2[3,] / tbl_st),
                 lose = 100 * as.vector(tbl_st_wl2[1,] / tbl_st))
# Calculate the boundaries of categories on the horizontal axis
df <- df %>%
    mutate(xmax = cumsum(status_pct),
           xmin = xmax - status_pct)
## Remove the variable status_pct because we won't use it
df$status_pct <- NULL
# Reshape the data frame
df_long <- df %>% gather(key = result, value = voteshare, win:lose)
##################################################
## COMPARE df_long with df
## to understand what gather() has accomplished
## df
## df_long
###################################################
# Calculate the boundaries of categories on the vertical axis
df_long_1 <- df_long %>%
    group_by(status) %>%
    mutate(ymax = cumsum(voteshare),
           ymin = ymax - voteshare)
# Detemine the locations to put texts
df_long_1 <- df_long_1 %>%
    mutate(xtext = xmin + (xmax - xmin) / 2,
           ytext = ymin + (ymax - ymin) / 2,
           result = factor(result, levels = c("win", "zombie", "lose"),
                           labels = c("当選", "復活当選", "落選")))
# Make a mosaic plot
mosaic <- ggplot(df_long_1, aes(ymin = ymin, ymax = ymax,
                                xmin = xmin, xmax = xmax,
                                fill = result))
mosaic <- mosaic +
  geom_rect(color = I("grey")) +
  geom_text(aes(x = xtext, y = ytext, label = paste0(round(voteshare), "%"))) +
  geom_text(aes(x = xtext, y = 103, label = status), 
            family = "HiraginoSans-W3") +
  scale_fill_discrete(name = "選挙結果") +
  guides(fill = guide_legend(reverse = TRUE)) +
  labs(x = "", y = "")
print(mosaic)

モザイク図ができた。 モザイク図を作るのは少し大変だが、表の内容を直感的・視覚的に捉えることができる。 読者の立場にたって考えれば、多少の手間は惜しまずにモザイク図を作った方が良い。 この図の欠点は、場所を取るということである。