ggplot2でウォータフォールチャート？滝グラフ？を描く

売上とか利益とかでよく見るこんなグラフです。
ウォータフォールプロット？滝グラフ？とか呼ばれるらしいです。初めて知りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/0aeda30c-c1c2-db57-74f0-0517b7e8bc11.png)

# 例えばこんなデータで。

```R
# サンプルデータ
sanple_data <- data.frame(
	費目 = c("売上高", "売上原価",  "販管費", "営業外損益",　"特別損益",　"税金"),
	金額 = c(3251, -720, -420, -850, -281, -311),
	stringsAsFactors=F
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/8c582e9a-9693-4dab-699d-fa88bb522186.png)
※数字は適当です。

# パッケージを使うと楽。

いろいろ調べていると、お手軽なパッケージありました。
https://rkabacoff.github.io/datavis/Other.html#waterfall-charts

```R
# インストールして
install.packages("waterfalls")
library("waterfalls")

# こんな感じで。
waterfall(
	sanple_data, 
	calc_total=TRUE,  # 収支の差分のところを描画する
	total_axis_text = "利益", # そこの文字列
	total_rect_text_color="black", # そこの線の色
	total_rect_color="goldenrod1"  # そこの線の塗りつぶし
) 
```
実行すると、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/18f3d3a0-9e37-e28b-c86a-2cca7409ff5f.png)

なるほどらくちん。でも、こまごました部分はオプションを付けていくスタンスで、
できればggplotでスパっと描けないものかと調べてみて、

# ggplotで描く

作図用のデータ作って、`geom_rect` で描く感じ。
http://tomoshige-n.hatenablog.com/entry/2014/08/11/235816
https://gist.github.com/rentrop/36f07b67cb6c4b82088e2115fee2498f
などを参考にしました。

### 作図用のデータを作る。

```R
# 作図用のデータ作成
tmp <- sanple_data %>% 
mutate(
	end = cumsum( 金額 ), # 上端
	start = dplyr::lag(end, default = 0), # 下端
	type = if_else( 金額 >=0,"収入","支出"), # 色分けのため
	id = seq(1, n())
) %>% 
bind_rows(summarise(., 費目 = "利益", 金額 =last(end), start = 0, end = last(end), id = n()+1L, type = "利益")) # 収支の差分のところ
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/8ccf68fc-da4c-2650-4e74-002f450197b5.png)

こんな感じ。よく読めはなるほどだけど、元データの項目名以外はコピペでいけそう。

### グラフを描く

```R
library("tidyverse")

# 可視化
tmp %>% ggplot(aes(費目, fill = type)) + 
	geom_rect(aes(
		x = 費目 ,
		xmin = id-0.5, xmax= id+0.5, # 隙間なくするなら0.5、隙間空けるなら小さくする
		ymin = end, ymax= start 
	)) +
	geom_text(aes( # 文字を入れる
		x = id ,
		y = (start+end)/2, # グラフの中央に
		label = str_c(費目,"\n",金額) 
	)) +
	labs(x = "", y = "金額", fill= "")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/830a619a-e417-d1e0-f2c5-a93ef3c8eaae.png)
できた！

# facetで複数描画する。
ggplotで描きたかったのは、facet_wrapで複数一度に書けるんじゃないかなと思ったゆえで。
下記みたいなデータで、、

```R
library(tidyverse)

# サンプルデータ
sanple_data <- data.frame(
	費目 = c(
		"売上", "売上原価",  "販管費", "営業外損益", "特別損益", "税金",
		"売上", "売上原価",  "販管費", "営業外損益", "特別損益", "税金",
		"売上", "売上原価",  "販管費", "営業外損益", "特別損益", "税金"
	),
	金額 = c(
		3251, -720,  -420, -850, -281, -311,
		4728, -1650, -130, -250, -975, -535,
		2560, -320,  -540, -90,  -154, -241
	),
	支店 = c(
		rep("西日本",6),
		rep("東日本",6),
		rep("海外",6)
	),
	stringsAsFactors=F
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/a49e7ad4-0bec-59b5-ff1f-8cb33e9cb851.png)

### グラフを描く

```R
# 作図用のデータ作成
tmp <- sanple_data %>% 
group_by(支店)%>%   # ※ここを追記
mutate(
	end = cumsum( 金額 ),
	start = dplyr::lag(end, default = 0),
	type = if_else( 金額 >=0,"収入","支出"),
	id = seq(1, n())
) %>% 
bind_rows(summarise(., 費目 = "利益", 金額 =last(end), start = 0, end = last(end), id = n()+1L, type = "利益"))

# 可視化
tmp %>% ggplot(aes(費目, fill = type)) + 
	geom_rect(aes(
		x = 費目 ,
		xmin = id -0.45, xmax = id + 0.45,
		ymin = end, ymax = start
	)) +
	geom_text(aes(
		x = id ,
		y=(start+end)/2,
		label=str_c(費目,"\n",金額)
	)) +
	labs(x = "", y = "金額", fill="") +
	facet_wrap(~支店)   # ※ここを追記
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22963/3a779b28-4cbc-e768-9ad3-b2a3afd1d413.png)

できた！