売上とか利益とかでよく見るこんなグラフです。
ウォータフォールプロット?滝グラフ?とか呼ばれるらしいです。初めて知りました。
例えばこんなデータで。
# サンプルデータ
sanple_data <- data.frame(
費目 = c("売上高", "売上原価", "販管費", "営業外損益", "特別損益", "税金"),
金額 = c(3251, -720, -420, -850, -281, -311),
stringsAsFactors=F
)
パッケージを使うと楽。
いろいろ調べていると、お手軽なパッケージありました。
https://rkabacoff.github.io/datavis/Other.html#waterfall-charts
# インストールして
install.packages("waterfalls")
library("waterfalls")
# こんな感じで。
waterfall(
sanple_data,
calc_total=TRUE, # 収支の差分のところを描画する
total_axis_text = "利益", # そこの文字列
total_rect_text_color="black", # そこの線の色
total_rect_color="goldenrod1" # そこの線の塗りつぶし
)
なるほどらくちん。でも、こまごました部分はオプションを付けていくスタンスで、
できればggplotでスパっと描けないものかと調べてみて、
ggplotで描く
作図用のデータ作って、geom_rect
で描く感じ。
http://tomoshige-n.hatenablog.com/entry/2014/08/11/235816
https://gist.github.com/rentrop/36f07b67cb6c4b82088e2115fee2498f
などを参考にしました。
作図用のデータを作る。
# 作図用のデータ作成
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 = "利益")) # 収支の差分のところ
こんな感じ。よく読めはなるほどだけど、元データの項目名以外はコピペでいけそう。
グラフを描く
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= "")
facetで複数描画する。
ggplotで描きたかったのは、facet_wrapで複数一度に書けるんじゃないかなと思ったゆえで。
下記みたいなデータで、、
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
)
グラフを描く
# 作図用のデータ作成
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(~支店) # ※ここを追記
できた!