2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

R言語:複数カテゴリboxplot+jitterplot問題

Posted at

前回の続き。
嵌ったのは個々から。

起こったこと

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)

image.png

さて、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)

結果はこうだ。

image.png

一応解説をすると、
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が存在しない。そうすると結果としては以下だ。

image.png

うーん美しくない。
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)

image.png

だが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)

image.png

これが欲しかった図である。
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)

image.png

やったぜ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?