2015年5月7日木曜日

ggplotで積み上げ棒グラフ その2 負の積み上げ

棒グラフの積み上げ順序はわかりました。今度は、負の値がある利益のようなデータをプロットしてみたいと思います。
この表をExcel やCalcで棒グラフにするとこんな風になります。正の値と負の値を別々に積み上げます。(Calcで描いたものです。)

利益

2011201220132014
商品A10204080
商品B10060-1020
商品X-20-30010
商品Y-30-40-4020
Rのbarplotやggplotでは、こんなふうにはなりません。ggplotで描いてみるとこんな風になりました。2011の項目については、A,Bを100まで積み上げて、X,Yを下に-50積み上げています。考えてみると、Excelより自然な処理だと思いますが、この図、何がなんだかわかりません。
ggplotの棒グラフは基本的にカウントデータを前提にしたものなのでしょうから、最小値が0でない場合は警告を出しています。

> profit.ldf <- melt(profit.tbl, value.name = "利益")
> qplot(data = profit.ldf, x = 年, y = 利益, fill = 商品, geom = "bar",
+       stat = "identity", position = "stack") +
+   guides(fill = guide_legend(reverse = TRUE))
Warning message:
In loop_apply(n, do.ply) : Stacking not well defined when ymin != 0



私が必要としているのはExcel風の棒グラフなのでExcelで描けばよいのですが。
結局、積み上げの部分を正と負に分割して作成して合成しました。レイヤーって便利です。やっぱり警告も出ますが、意図したようになったわけだから無視します。でも、私の知らない他の良い方法がありそうな気もするのです。

> fig <- ggplot() +
+   #正の積み上げ
+   geom_bar(data = subset(profit.ldf, 利益 > 0), aes(x = 年, y = 利益, fill = 商品),
+            stat = "identity", position = "stack") +
+   #負の積み上げ
+   geom_bar(data = subset(profit.ldf, 利益 < 0), aes(x = 年, y = 利益, fill = 商品),
+            stat = "identity", position = "stack") +
+   #合計の折れ線
+   geom_line(data = melt(xtabs(利益 ~ 年, data = profit.ldf)), aes(x = 年, y = value),
+             color = "black") +
+   #合計の点グラフ
+   geom_point(data = melt(xtabs(利益 ~ 年, data = profit.ldf)), aes(x = 年, y = value),
+              color = "black", pch = 23, bg = "white") + #ggplotでもpch使えるんだ!
+   #x軸
+   geom_hline(yintercept=0, color = "black")
> fig + guides(fill = guide_legend(reverse = TRUE)) #凡例を逆転
Warning message:
In loop_apply(n, do.ply) : Stacking not well defined when ymin != 0