ggplot2の棒グラフの上や下に値をラベルとして書き込む方法のメモ
ggplot2の棒グラフの上や下に値をラベルとして書き込む方法のメモ。とりあえず簡単なgeom_col()の場合で書いていく。
上に書くだけならgeom_text()で位置を調整して書けばいい。
例えば次のようなデータの場合。
library(ggplot2) df <- data.frame(X = LETTERS[1:4], value = c(10, 20, 30, 40)) df
##   X value
## 1 A    10
## 2 B    20
## 3 C    30
## 4 D    40
ggplot(df, aes(x = X, y = value)) + geom_col()

この棒グラフの上に値を書き込みたいと思いたい場合、geom_text()を使い、そのままの位置に書くと棒グラフに被るので、棒グラフの上に描画するようにvjustやnudge_yを使ってラベルの位置を調整しながら次のようにかける。
ggplot(df, aes(x = X, y = value)) + geom_col() + geom_text(aes(label = value), nudge_y = 2)

ggplot(df, aes(x = X, y = value)) + geom_col() + geom_text(aes(label = value), vjust = -0.5) + ylim(0, 42)

nudge_yとvjustの違いは上のコードを見てもらえば分かる通り、nudge_yの場合はいい塩梅に描画範囲を調整してくれるが、vjustは描画範囲を調整してくれないので、自分で調整する必要がある。
じゃあ、いつもnudge_yでいいじゃないかとなるかもしれないが一部画面ではvjustのほうが都合がいい場合がある。
例えば次のようなデータで横棒グラフを描く場合を考える。
df <- data.frame(X1 = rep(LETTERS[1:4], 3), X2 = rep(LETTERS[24:26], each = 4), value = seq(10, by = 10, length.out = 12)) head(df)
##   X1 X2 value
## 1  A  X    10
## 2  B  X    20
## 3  C  X    30
## 4  D  X    40
## 5  A  Y    50
## 6  B  Y    60
ggplot(df, aes(x = X1, y = value, fill = X2)) + geom_col(position = position_dodge())

このとき、nudge_yだと次のようになる。
ggplot(df, aes(x = X1, y = value, fill = X2)) + geom_col(position = position_dodge()) + geom_text(aes(label = value), position = position_dodge() ,nudge_y = 2)
## Error in `geom_text()`:
## ! Both `position` and `nudge_x`/`nudge_y` are supplied.
## ℹ Only use one approach to alter the position.
position = position_dodge()を使ってずらしたいと思ったとおりにいかない(ここでposition = position_dodge()をしないと積み上げグラフの位置で数字が書かれてしまう)。ドキュメントにもちゃんと、positionとnudge_xは一緒に使えないと書いている。
ここで、vjustを使うと思ったとおりに行く。
ggplot(df, aes(x = X1, y = value, fill = X2)) + geom_col(position = position_dodge()) + geom_text(aes(label = value), position = position_dodge(0.85), vjust = -0.5) + ylim(c(0, 130))

こんな感じに行く。
さらに正負の値が混じった次のようなデータを考える。
df <- data.frame(X = c("A", "B", "C", "D"), value = c(10, 20, -10, -20)) ggplot(df, aes(x = X, y = value)) + geom_col()

このとき、正の値の場合は棒グラフの上に、負の値の場合は棒グラフの下に描画したいと思った場合を考える。単純にnudge_yなどで位置を書くと正負の場合分けができない。
ggplot(df, aes(x = X, y = value)) + geom_col() + geom_text(aes(label = value), nudge_y = 2)

結論から言うとifelse()などで条件づけするとかける。
ggplot(df, aes(x = X, y = value)) + geom_col() + geom_text(aes(label = value), nudge_y = ifelse(df$value >= 0, 2, -2))

これで思ったグラフがかける。