ggplotのfacet_wrapの個別のエリアに描画


ggplotでfacet_wrap使ってふく数枚のグラフを並べて表示させた後、それぞれのファセットに個別にgeom_***で何かを書き込みたいときのやり方。

まず、ggplotでfacet_wrapを使って描画する。
ちなみに、countdataは、ある3つ問からなる質問紙を企業に実施して得られた回答(5段階尺度)を、企業の人数規模(5段階)ごとに平均と標準偏差を求めたものを格納してる。

変数名 内容
q c(rep("Q1-1",5),rep("Q1-2",5),rep("Q1-3",5))として、質問番号を指定してる。
no 人数規模(本当は1:1000人以上、2:500~999人、3:300~499人、4:100~299人、5:~99人という区分だが、長ったらしく書きたくなかったので、とりあえずc(1:5)と数字ベクトルを当てはめてる。)
Mean 平均
SD 標準偏差

まあ、要するに、こんなデータ。

q no Mean SD
"Q1-1" 1 3.285714 1.1126973
"Q1-1" 2 3.400000 1.0749677
"Q1-1" 3 3.111111 0.9633818
"Q1-1" 4 3.479592 1.0476246
"Q1-1" 5 3.245614 1.0476246
"Q1-2" 1 2.714286 0.4879500
"Q1-2" 2 3.200000 0.9189366
: : : :

で、まずは描画。

g<-ggplot(countdata,aes(x=factor(no),y=Mean))+
  geom_bar(stat="identity",aes(fill=factor(no)))+
  geom_errorbar(aes(ymax=Mean+SD,ymin=Mean-SD),width=0.2)+
  facet_wrap(.~q)

このQ1-3のエリアにだけgeom_textやgeom_segmentを使って書き込みしたい。
その準備として、以下のようなデータフレームsigを作る。

sig<-data.frame(
  x=c(2,2,4),
  xend=c(2,4,4),
  y=c(4.75,6,6),
  yend=c(6,6,5.5),
  q=c("Q1-3","Q1-3","Q1-3")
)

これは、3つのセグメントを描画したいので、各変数は3つの要素で構成されているが、別に一個一個別々にgeom_segmentで描画するのでも構わない。その場合には、各変数の要素は1個でよい。
ポイントはqという変数。これはfacet_wrapを使うときにグループ分け用に渡す変数。これを持っておくのがポイント。

g<-g+geom_segment(data=sig,aes(x=x,xend=xend,y=y,yend=yend))

するとこうなる。

さらにテキストも付け加える。

sig.text <- data.frame(
  x=3,
  y=6.2,
  label="P=0.078, †",
  q="Q1-3"
)
g<g+geom_text(data=sig.text,aes(x=x,y=y,label=label))

ということで完成!

参考:
ggplot2の個々のファセットのテキストに注釈を付ける

補筆:うっかり嵌まりそうなとこ(2021/3/19追記)

以下のようにやると、ファセット分けまではうまくいきますが、そのあとに描画を付け加える段階でエラーになります。
ポイントはfill=factor(no)を入れる位置。
これをggplotの最初の設定の段階でやってしまうと、
「is.factor(x)でエラー: オブジェクト 'no' がありません」
というエラーが出ます。

g<-ggplot(countdata,aes(x=factor(no),y=Mean,aes(fill=factor(no))))+
  geom_bar(stat="identity")+
  geom_errorbar(aes(ymax=Mean+SD,ymin=Mean-SD),width=0.2)+
  facet_wrap(.~q)
plot(g)

g<g+geom_text(data=sig.text,aes(x=x,y=y,label=label))
plot(g)

あくまで、fillの設定はgeom_barの中で行う必要があります。