いろいろ倉庫

KNIME、EXCEL、R、Pythonなどの備忘録

【R】ggplot2メモ③(Multi-level label棒グラフ)

・お題:先日、ggplotで棒グラフを作成した。X軸のラベルを二層にしたい場合があったので、やり方をメモしたい。基本的にはfacetを使う。

 

・ライブラリを読み込み、データを作る。

> library(tidyverse)
> set.seed(1)


> TestComp. <- rep(c("Vehicle", "Comp.A(mg/kg)", "Comp.B(mg/kg)"),
+                  times = c(10, 30, 30))

 

> Dose <- c(rep(0, times = 10),
+           rep(c(1, 3, 10), each = 10),
+           rep(c(1, 3, 10), each = 10))

 

> Score <- c(rnorm(10, mean = 10, sd = 2),
+            rnorm(10, mean = 10, sd = 2),
+            rnorm(10, mean = 15, sd = 2),
+            rnorm(10, mean = 20, sd = 2),
+            rnorm(10, mean = 15, sd = 2),
+            rnorm(10, mean = 20, sd = 2),
+            rnorm(10, mean = 20, sd = 2))

 

> df <-
+   data.frame(TestComp., Dose, Score) %>% 
+   group_by(TestComp., Dose) #TestComp.とDoseの条件ごとにGroup化しておく。

 

・作ったデータはこんな感じ。

> df

・データを読み込む。

> p <- ggplot(data = df)

 

・とりあえず、X軸のラベルが単層の場合でやってみる。

> bar <- p +
+   geom_bar(mapping = aes(x = factor(Dose),
+                          y = Score,
+                          fill = factor(TestComp.)),
+            position="dodge",
+            stat = "summary",
+            fun = "mean",
+            color = "gray30",
+            width = 0.6)+
+   scale_fill_manual(name = "Groups", labels = c("Comp.A", "Comp.B", "Vehicle"), values = c("black", "red", "white")) + #個別の色を設定
+   geom_point(mapping = aes(x = factor(Dose), 
+                            y = Score,
+                            fill = factor(TestComp.)),
+              position = position_dodge(0.6),
+              color = "gray") +
+   scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) +
+   labs(title="title1",
+        x = "Dose(mpk)",
+        y = "Score")+
+   theme_classic()
> plot(bar)

・この時点で、「並びが悪い」「Vehicleが太い」など改良の余地あり。とりあえず、このままfacetしてみる。

> bar2 <- bar +
+   facet_grid(. ~ as.factor(TestComp.),
+              switch = "x") +
+   theme(strip.placement = "outside",
+         strip.background = element_rect(fill = "white"),
+         axis.title.x = element_blank())
> plot(bar2)

・分からないではないが、各Groupで余分なDoseができてしまっている。もうちょっとうまいことやりたい。以下のサイトを参考にさせて頂いた。

dmitrijskass.netlify.app

・一気にまとめていく。

> bar3 <- p +
+   geom_bar(mapping = aes(x = as.factor(Dose),
+                          y = Score,
+                          fill = factor(TestComp., levels=c("Vehicle", "Comp.A(mg/kg)" , "Comp.B(mg/kg)"))), #levelsでfactorの序列を指定する。

+            position="dodge",
+            stat = "summary",
+            fun = "mean",
+            color = "gray30",
+            width = 0.6)+
+   scale_fill_manual(name = "Groups", labels = c("Vehicle", "Comp.A", "Comp.B"), values = c("white","black", "red")) + #序列を指定しつつ、個別の色を設定
+   geom_point(mapping = aes(x = factor(Dose), 
+                            y = Score,
+                            fill = factor(TestComp.)),
+              position = position_dodge(0.6),
+              color = "gray") +
+   scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) +
+   labs(title="title1",
+        x = "Dose(mpk)",
+        y = "Score") +
+   theme_classic() +
+   facet_grid(. ~ factor(TestComp., levels=c("Vehicle", "Comp.A(mg/kg)" , "Comp.B(mg/kg)")), #表示のための序列を指定
+              scales = "free_x", # 空カラムがないように、GroupごとにDoseを変えられるようにする。
+              space = "free_x",  # カラムの太さを揃える。
+              switch = "x")+

+   theme(strip.placement = "outside", #facetしたグループの場所を下に持ってくる
+         axis.title.x = element_blank(), #X軸ラベルを消す
+         text = element_text(size = 15) #ついでに、文字の大きさを変える
+         )
> plot(bar3)

 

・そもそもデータフレームの時点でfactor化して序列を設定しておけば、描画時にいちいち指定する必要がなくなる。少しだけシンプルになる。

> df$TestComp. <- factor(df$TestComp., levels=c("Vehicle", "Comp.A(mg/kg)" , "Comp.B(mg/kg)")) #序列を指定する。
> df$Dose <- factor(df$Dose) #数字もラベルとして使用するならfactor化しておく。

 

・最初のグラフでvehicle群が太くなっていたので、少し修正しておく。
> bar4 <- ggplot(data = df,
+             mapping = aes(x = Dose,
+                           y = Score,
+                           fill = TestComp.))+
+   geom_bar(stat = "summary",
+            fun = "mean",
+            color = "gray30",
+            width = 0.6,
+            position = position_dodge2(preserve = "single"))+#カラムの幅を揃える
+   scale_fill_manual(name = "Groups", labels = c("Vehicle", "Comp.A", "Comp.B"), values = c("white","black", "red")) +
+   geom_point(mapping = aes(x = Dose, 
+                            y = Score,
+                            fill = TestComp.),
+              position = position_dodge(0.6),
+              color = "gray") +
+   scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) +
+   labs(title="title1",
+        x = "Dose(mpk)",
+        y = "Score") +
+   theme_classic()
> plot(bar4)

・facet版はコードも結果も全く同じなので、割愛。

 

 

おわり。