LoginSignup
1
3

More than 3 years have passed since last update.

R言語でマクドナルドの業績をウォーターフォール可視化

Last updated at Posted at 2021-03-21

マクドナルドの損益計算書を取得します

2020年12月期(連結)の営業利益が312億9000万円と、9年ぶりに最高益を記録したマクドナルドの損益計算書(PL)のウォーターフォール図を作ってみました。
「ggplot2」が装備する、矩形描画のための「geom_rect」を使います。
※プログラム言語初心者レベルなので、冗長性のあるコードになっているかもしれません。ご容赦ください。

ウォーターフォール図作成の参考にしたのは
https://qiita.com/tayohei@github/items/1a19e1b5a05dccfa8c71
https://www.jigsawacademy.com/waterfall-charts-using-ggplot2-in-r/
の2つです。

マクドナルドの決算データはこちらから取得しました(単位:百万円)。

https://www.mcd-holdings.co.jp/ir/summary/#hd_summary_05

支出はマイナスにしました。

ウォーターフォール1

一応、確認のための計算をしました。
サイトにある数字は十万円以下が丸められているので、確認した数字の最後の桁が微妙に異なりますが、このまま使います。

ウォーターフォール2

データフレーム型にします。

pl_data <- data.frame(
    items = c("売上高", "売上原価", "販売費及び一般管理費", "営業外収益", "営業外費用", "特別利益", "特別損失", "法人税住民税及び事業税", "法人税等調整額", "当期純利益"),
    amount = c(288332, -230075, -26966, 1421, -1286, 0, -870, -10140, -226, 20186),
    stringsAsFactors=F
)

pl_data #データ確認
                    items  amount
1                  売上高  288332
2                売上原価 -230075
3    販売費及び一般管理費  -26966
4              営業外収益    1421
5              営業外費用   -1286
6                特別利益       0
7                特別損失    -870
8  法人税住民税及び事業税  -10140
9          法人税等調整額    -226
10             当期純利益   20186

「ggplot2」用にデータを加工します

今回は「ggplot2」を使います。
データの加工をします。

#ggplot2に適用するためのデータ加工
#seq_along()はデータセットのインデックス化したベクトルを返
#データフレームの場合は列単位。リストの場合はリスト単位
pl_data$items <- as.factor(pl_data$items) #ファクター型に変換
pl_data$id <- seq_along(pl_data$amount) #上記参照
pl_data$type <- ifelse(pl_data$amount > 0, "収入", "支出") #「収入」「支出」がわかる列を追加
# items列の"売上高", "営業外損益"の行のtype列に"net" と追記。収入のネット金額
pl_data[pl_data$items %in% c("売上高", "営業外収益"), "type"]  <- "net" 
pl_data #データ確認
                    items  amount id type
1                  売上高  288332  1  net
2                売上原価 -230075  2 支出
3    販売費及び一般管理費  -26966  3 支出
4              営業外収益    1421  4  net
5              営業外費用   -1286  5 支出
6                特別利益       0  6 支出
7                特別損失    -870  7 支出
8  法人税住民税及び事業税  -10140  8 支出
9          法人税等調整額    -226  9 支出
10             当期純利益   20186 10 収入

累積値を追加します。

pl_data$end <- cumsum(pl_data$amount) #cumsum は累積
pl_data #データ確認
                    items  amount id type    end
1                  売上高  288332  1  net 288332
2                売上原価 -230075  2 支出  58257
3    販売費及び一般管理費  -26966  3 支出  31291
4              営業外収益    1421  4  net  32712
5              営業外費用   -1286  5 支出  31426
6                特別利益       0  6 支出  31426
7                特別損失    -870  7 支出  30556
8  法人税住民税及び事業税  -10140  8 支出  20416
9          法人税等調整額    -226  9 支出  20190
10             当期純利益   20186 10 収入  40376

この後「geom_rect」を使い描画するので、矩形範囲を指定するための加工をします。

#end列に end列の1行目を外したものと、末尾に0を加えた ベクトルに差し替える
pl_data$end <- c(head(pl_data$end, -1),0)
pl_data #データ確認
                    items  amount id type    end
1                  売上高  288332  1  net 288332
2                売上原価 -230075  2 支出  58257
3    販売費及び一般管理費  -26966  3 支出  31291
4              営業外収益    1421  4  net  32712
5              営業外費用   -1286  5 支出  31426
6                特別利益       0  6 支出  31426
7                特別損失    -870  7 支出  30556
8  法人税住民税及び事業税  -10140  8 支出  20416
9          法人税等調整額    -226  9 支出  20190
10             当期純利益   20186 10 収入      0

#start列に 0とend列の-1行目にしたベクトルに差し替える
pl_data$start <- c(0, head(pl_data$end, -1))
pl_data #データ確認
                    items  amount id type    end  start
1                  売上高  288332  1  net 288332      0
2                売上原価 -230075  2 支出  58257 288332
3    販売費及び一般管理費  -26966  3 支出  31291  58257
4              営業外収益    1421  4  net  32712  31291
5              営業外費用   -1286  5 支出  31426  32712
6                特別利益       0  6 支出  31426  31426
7                特別損失    -870  7 支出  30556  31426
8  法人税住民税及び事業税  -10140  8 支出  20416  30556
9          法人税等調整額    -226  9 支出  20190  20416
10             当期純利益   20186 10 収入      0  20190

#列を並び替える
pl_data <- pl_data[, c(3,1,4,6,5,2)]
pl_data #データ確認
   id                  items type  start    end  amount
1   1                 売上高  net      0 288332  288332
2   2               売上原価 支出 288332  58257 -230075
3   3   販売費及び一般管理費 支出  58257  31291  -26966
4   4             営業外収益  net  31291  32712    1421
5   5             営業外費用 支出  32712  31426   -1286
6   6               特別利益 支出  31426  31426       0
7   7               特別損失 支出  31426  30556    -870
8   8 法人税住民税及び事業税 支出  30556  20416  -10140
9   9         法人税等調整額 支出  20416  20190    -226
10 10             当期純利益 収入  20190      0   20186

pl_data_bkup <- pl_data #バックアップ用

「str」でデータの型を確認します。

str(pl_data)
'data.frame':   10 obs. of  6 variables:
 $ id    : int  1 2 3 4 5 6 7 8 9 10
 $ items : Factor w/ 10 levels "営業外収益","営業外費用",..: 7 6 8 1 2 5 4 9 10 3
 $ type  : chr  "net" "支出" "支出" "net" ...
 $ start : num  0 288332 58257 31291 32712 ...
 $ end   : num  288332 58257 31291 32712 31426 ...
 $ amount: num  288332 -230075 -26966 1421 -1286 ...

#なお、下記にすると、ggploto2実行時にエラーが出るfactor型でないといけない(後でtypeと併せてfactorに変換)
pl_data$items <- as.character(pl_data$items)

str(pl_data)
'data.frame':   10 obs. of  6 variables:
 $ id    : int  1 2 3 4 5 6 7 8 9 10
 $ items : chr  "売上高" "売上原価" "販売費及び一般管理費" "営業外収益" ...
 $ type  : chr  "net" "支出" "支出" "net" ...
 $ start : num  0 288332 58257 31291 32712 ...
 $ end   : num  288332 58257 31291 32712 31426 ...
 $ amount: num  288332 -230075 -26966 1421 -1286 ...

pl_data$type <- as.factor(pl_data$type) #ファクター型に変換
pl_data$items <- as.factor(pl_data$items) #ファクター型に変換

str(pl_data)
'data.frame':   10 obs. of  6 variables:
 $ id    : int  1 2 3 4 5 6 7 8 9 10
 $ items : Factor w/ 10 levels "営業外収益","営業外費用",..: 7 6 8 1 2 5 4 9 10 3
 $ type  : Factor w/ 3 levels "net","支出","収入": 1 2 2 1 2 2 2 2 2 3
 $ start : num  0 288332 58257 31291 32712 ...
 $ end   : num  288332 58257 31291 32712 31426 ...
 $ amount: num  288332 -230075 -26966 1421 -1286 ...

「ggplot2」と「geom_rect」を使います

「geom_rect」を使います。
xmin、xmax、ymin、ymaxで矩形範囲を指定しています。

library(ggplot2)
#geom_rect は 長方形描く。0.45+0.45の幅の長方形
#0.5より小さければ矩形の間に隙間ができる
ggplot(pl_data, aes(items, fill=type)) + geom_rect(aes(x = items, xmin = id-0.45, xmax = id+0.45, ymin = end, ymax = start)) + theme_gray (base_family = "HiraKakuPro-W3")
#base_family = "HiraKakuPro-W3"は、Macでの文字化け回避用

ウォーターフォール3

しかし、このままだとx軸の表示順番が以下のようになっています(最後の行)。
順番を入れ替えます。

pl_data$items
 [1] 売上高                 売上原価               販売費及び一般管理費  
 [4] 営業外収益             営業外費用             特別利益              
 [7] 特別損失               法人税住民税及び事業税 法人税等調整額        
[10] 当期純利益            
10 Levels: 営業外収益 営業外費用 当期純利益 特別損失 特別利益 売上原価 ... 法人税等調整額

#ファクターの水準の順序を入れ替える
#http://cse.naro.affrc.go.jp/takezawa/r-tips/r/16.html
#上記を参考に、factor関数でlevels引数を指定
pl_data$items <- factor(pl_data$items, levels=c("売上高", "売上原価", "販売費及び一般管理費", "営業外収益", "営業外費用", "特別利益", "特別損失", "法人税住民税及び事業税", "法人税等調整額", "当期純利益"))
pl_data$items #データ確認
[1] 売上高     売上原価   販管費     営業外損益 特別損益   税金       利益      
Levels: 売上高 売上原価 販管費 営業外損益 特別損益 税金 利益

再度描画します。
※下記のように「Ignoring unknown aesthetics: x 」というメッセージが出るのですが、まだ調べがついていません。
※意図通りの可視化はできているので、このまま進めます。
 

#再描画設定
options(scipen=100) #Y軸が指数表示になるのでそれを回避
pl_plot <- ggplot(pl_data, aes(items, fill=type)) + geom_rect(aes(x = items, xmin = id-0.45, xmax = id+0.45, ymin = end, ymax = start)) + theme_gray (base_family = "HiraKakuPro-W3")+theme(axis.text.x = element_text(size = 6))
pl_plot

ウォーターフォール4

各バーにテキストを追加します。

#矩形領域に文字を入れる
library("stringr")
pl_plot2 <- pl_plot + geom_text(aes( #文字追加。位置は以下で指定
        x = id ,
        y = (start+end)/2, #グラフの中央に文字を配置
        label = str_c(items,"\n",amount),
        family = "HiraKakuPro-W3" #Macでのプロット内ので文字化け防止
    )
    ,size = 3,)+ labs(x = "", y = "amount", fill= "") #軸ラベル付与
#sizeの位置はgeom_text(aes(label=***), size=x.x)

#描画実行
pl_plot2

ウォーターフォール5

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3