(番外編1)Rを使ったグラフィック -ggplot2でウォーターフォール図-
ウォーターフォールチャートとは
まずは、Wikipediaから引用しましょう。
滝グラフ(たきグラフ、英語:Waterfall chart)は正負の値の累積的影響を判断する際に役立つ可視化用グラフである。 レンガが宙に浮いているように列が表示されることから、飛行レンガグラフ(英語:flying bricks chart)やマリオ (ゲームキャラクター)グラフ(英語:Mario chart)として知られている。 戦略的コンサルティング会社であるマッキンゼー・アンド・カンパニーにより、顧客向けプレゼンテーション手法として普及した。[1][2] インベントリ分析や性能解析などの多様な定量分析にて利用されている。
まぁ、最初の一文だけで十分ですよね。「正負の値の累積的影響を判断する際に役立つ可視化用グラフ」です。
データの作成
まずは、仮想データを作成します。仮想データは以下のようなバランスシートを考えます。支出・収入などですね。これをウォーターフォールチャートで可視化します。
> #仮想データの構築 > balance <- data.frame(desc = c("Starting Cash","Sales", "Refunds", "Payouts", "Court Losses","Court Wins", "Contracts", "End Cash"), amount = c(2000,3400, -1100, -100, -6600, 3800, 1400, 2800)) > > #結果の表示 > balance desc amount 1 Starting Cash 2000 2 Sales 3400 3 Refunds -1100 4 Payouts -100 5 Court Losses -6600 6 Court Wins 3800 7 Contracts 1400 8 End Cash 2800
さて、ウォーターフォールチャートではグラフの始点と終点が必要です。それを次にデータフレームとして作成する必要があります。具体的な手順は下のコマンドの通りです。
> #まずは、balance$descをfactorにする(図をかくために) > balance$desc = factor(balance$desc,levels=balance$desc) > > #idリストを作成 > balance$id = seq_along(balance$amount) > > #収入か、支出かを判別する変数を構築 > balance$type = ifelse(balance$amount >0,"in","out") > > #balance$descの最初と最後のtype変数に"net"を入れる(支出・収入ではない)。 > balance[balance$desc %in% c("Starting Cash", "End Cash"),"type"] <- "net" > > #各数値を計算した後の値を作成する。 > #cumsumは1,2,3なら、1, (1)+2, (1+2)+3と計算するような関数 > balance$end = cumsum(balance$amount) > > #balance$endの最後の項を0に変更 > #head(x,-1)で最後の1項を除いたベクトル > balance$end = c(head(balance$end,-1),0) > > #startはbalance$endの1つ前の項の値である。 > #i+1番目の始点の値 = i番目のendの値である > balance$start = c(0,head(balance$end,-1)) > > #変数の表示順番を整える(しなくてもok) > balance = balance[,c(3,1,4,6,5,2)] > > #データフレーム > balance id desc type start end amount 1 1 Starting Cash net 0 2000 2000 2 2 Sales in 2000 5400 3400 3 3 Refunds out 5400 4300 -1100 4 4 Payouts out 4300 4200 -100 5 5 Court Losses out 4200 -2400 -6600 6 6 Court Wins in -2400 1400 3800 7 7 Contracts in 1400 2800 1400 8 8 End Cash net 2800 0 2800
さて、これを用いると、ウォーターフォールチャートは簡単に書けます。以下のようなggplotを行います。具体的に関数が何をしているのかは中に書いてあります。
######### ##plot### ######### library(ggplot2) #plot1 #geom_rectグラフの幅と高さを指定して描画する関数 #xmax-xminがグラフの幅です。・・・0.90です(このためうまく棒の間に空白が空きます) #また、xmin, xmaxは棒の位置を表しています。ここでxmin=id-0.45,xmax=id+0.45としていますから、id=1のものは0.55 ~ 1.45のところに描かれます。(実際そうなってるはず), ymin, ymaxは棒の長さを示しています。ymin=startなので最初の棒は0 ~2000までの幅を取ります。 ggplot(balance,aes(desc,fill=type))+geom_rect(aes(x=desc,xmin=id-0.45,xmax=id+0.45,ymin=end,ymax=start))
結果はこのような図で得られました。
でも、なんだか下の変数が重なっていて見づらい。そこで、折り返して表示する方法を考えます。
#plot2 #文字列を折り返す関数を作成 strwr = function(str) gsub(" ","\n",str) #上のものと同様にグラフを作成. #scale_x_discrete:離散系の軸パラメータを変更する。ラベルをね。breaksは何で区切るか ggplot(balance, aes(fill = type)) + geom_rect(aes(x = desc,xmin = id - 0.45, xmax = id + 0.45, ymin = end, ymax = start)) + scale_x_discrete("", breaks = levels(balance$desc),labels = strwr(levels(balance$desc)))
すると、奇麗になります!
まとめ
今回は、少しマニアックにggplot2でウォーターフォールチャートを作ることに挑戦しました。参照した記事はこちらです。ggplot2: Waterfall Charts | Learning R。ただ、これの最後にある文字を入れるのが、うまくいかず...最後は挫折したのでここまでにします。いい方法があれば教えてください。それでは。