前回の続き。
嵌ったのは個々から。
起こったこと
boxplot+jitterplotで示せばt検定しろとか言われないと理解したワイ。
片っ端からbox jitterしていたのだ。
問題は欠損カテゴリが出現したときに起こった。
ggsave2 <- function(plot, wid=9, hei=9){
plot_name <- deparse(substitute(plot))
file_name <- paste(plot_name, ".png", sep = "",collapse = "")
ggsave(filename = file_name,plot = plot,device = "png",width = wid, height = hei,dpi = 300,units = "cm")
}
dmd <- diamonds %>%
dplyr::filter(!as.character(cut) %in% c("Fair", "Good")) %>%
dplyr::filter(as.character(color) %in% c("G", "H", "I")) %>%
.[sample(x = 1:nrow(.), size = 500, replace = F),]
ってしておく。
ggsave2は、そのまま保存するようの関数だ。
dmd %>%
head()
A tibble: 6 x 10
carat cut color clarity depth table price x y z
1 0.52 Ideal H VS1 61 56 1699 5.15 5.23 3.17
2 0.61 Ideal I SI2 61.1 57 1401 5.46 5.49 3.34
3 0.31 Premium H VVS2 62.6 60 625 4.29 4.33 2.7
4 0.54 Very Good G SI1 63.8 57 1392 5.16 5.19 3.3
5 0.33 Ideal G IF 61 57 925 4.45 4.48 2.72
6 1.1 Ideal G SI1 62.3 56 5226 6.64 6.58 4.12
かんたんにはdiamondsのカテゴリ変数cutとcolorを少し絞った。
イメージとしてはカテゴリ変数の組み合わせとして10通り以下ぐらいがある状態を考えてほしい。
前回のbox+jitterするとこうだ。
p_boxjit <- ggplot()+theme_light()+
geom_boxplot(data = dmd,
aes(x=cut, y=carat), outlier.shape = NA)+
geom_jitter(data = dmd,
aes(x=cut, y=carat),
color="red", size=0.7)
ggsave2(p_boxjit)
さて、2つのカテゴリ変数の組み合わせの数がそれほど多くないなら、一つのbox jitterで見てみたいと思うよね。
一応こうすればできる。
pallet_ad_man <- c("#e41a1c",
"#377eb8",
"#4daf4a")
pallet_ad_white <- c("#ffffff",
"#ffffff",
"#ffffff")
p_bj2 <- ggplot()+theme_light()+
geom_boxplot(data = dmd,
aes(x=cut, y= carat, fill=color),
outlier.colour = NA)+
scale_fill_manual(values = pallet_ad_white)+
geom_point(data = dmd,
aes(x=cut, y=carat, color=color),
position = position_jitterdodge(jitter.width = 0.7), size=0.6)+
scale_color_manual(values = pallet_ad_man)
ggsave2(p_bj2, wid = 15)
結果はこうだ。
一応解説をすると、
boxplotの色はpallete_ad_whiteで全部白色に指定して、
jitter plotはgeom_pointで表現している。
でカテゴリ変数による横配置はpositon_jitterdodgeで実現する。
pallet_ad_manはpointでの色合いをしてしている。
これは完全に好み。
ただ、白色バックに黄色の点とか見にくいので適当に調整した。
ここまではいいだろう。
問題はここからだ。
特定の組み合わせに欠損があるとどうなるか。。。
dmd_lack <- dmd %>%
dplyr::filter(!(cut == "Ideal" & (color %in% c("G", "I"))))
p_bj3 <- ggplot()+theme_light()+
geom_boxplot(data = dmd_lack,
aes(x=cut, y= carat, fill=color),
outlier.colour = NA)+
scale_fill_manual(values = pallet_ad_white)+
geom_point(data = dmd_lack,
aes(x=cut, y=carat, color=color),
position = position_jitterdodge(jitter.width = 0.7), size=0.6)+
scale_color_manual(values = pallet_ad_man)
ggsave2(p_bj3, wid = 15)
Ideal群でG, Iとなるrowが存在しない。そうすると結果としては以下だ。
うーん美しくない。
Idealだけ無駄に横長になってしまって、全く嬉しくない。
boxplotだけなら、下のようにできる。
p_b3 <- ggplot()+theme_light()+
geom_boxplot(data = dmd_lack,
aes(x=cut, y= carat, fill=color),
position = position_dodge2(preserve = "single",
width = 0.5),
outlier.colour = NA)
ggsave2(p_b3, wid =12)
だがboxplotじゃあ足りないんだ。
p_bj4 <- ggplot()+theme_light()+
geom_boxplot(data = dmd_lack,
aes(x=cut, y= carat, fill=color),
position = position_dodge2(preserve = "single",
width = 0.5),
outlier.colour = NA)+
scale_fill_manual(values = pallet_ad_white)+
geom_point(data = dmd_lack,
aes(x=cut, y=carat, color=color),
position = position_jitterdodge(jitter.width = 0.7), size=0.6)+
scale_color_manual(values = pallet_ad_man)
ggsave2(p_bj4, wid = 15)
これが欲しかった図である。
ggplot2のバージョン等ではうまくイカないことがあるようだ。
もう一つのやり方は、欠損カテゴリを、プロットするべき範囲外の値で充填してしまう方法である。
dmd_lack_fix <- dmd_lack %>%
mutate(cut = factor(as.character(cut),
levels = c("Very Good", "Premium", "Ideal")),
color = factor(as.character(color),
levels = c("G", "H", "I"))) %>%
tidyr::complete(cut, color, fill = list(carat = -100))
何をしているかというと、
tidyr::completeで欠損カテゴリを充填するんだけど、
個々での欠損カテゴリは、cutがFairとか、colorがA,みたいなのも充填されてしまうので、
コード中のカテゴリのみだよってファクターの振り直しをしている。
それからコンプリートだね。
この辺すごく抽象度が低くて嫌になるけど、ここでは許してほしい。
p_bj5 <- ggplot()+theme_light()+
geom_boxplot(data = dmd_lack_fix,
aes(x=cut, y= carat, fill=color),
outlier.colour = NA) +
scale_fill_manual(values = pallet_ad_white)+
geom_point(data = dmd_lack_fix,
aes(x=cut, y=carat, color=color),
position = position_jitterdodge(jitter.width = 0.7), size=0.6)+
scale_color_manual(values = pallet_ad_man)+
coord_cartesian(ylim = c(0.2, 2.7))
ggsave2(p_bj5, wid=15)
やったぜ。