循环使用 ggplot 绘制箱线图

Loop to plot boxplot with ggplot

我用的是钻石df,

我想按类别为每个数字列绘制一个箱线图, 在这种情况下,类别将由“剪切”列定义。

我正在使用 for 循环来完成此任务,

这是我使用的代码:


##################################################################################
#                              Data                                              #
#                                                                                #
##################################################################################

data("diamonds")
basePlot <- diamonds[ names(diamonds)[!names(diamonds) %in% c("color", "clarity")] ]

##################################################################################

## set Plot view to 4 boxplots ##
par(mfrow = c(2,2))

## for-loop to boxplot all numerical columns ##

for (i in 1:(ncol(basePlot)-1)){
  print(ggplot(basePlot, aes(as.factor(cut), 
  basePlot[c(i)],color=as.factor(cut)))
        + geom_boxplot(outlier.colour="black",outlier.shape=16,outlier.size=1,notch=FALSE)
        + xlab("Diamond Cut")
        + ylab(colnames(basePlot)[i])
  )
}


控制台输出:

Don't know how to automatically pick scale for object of type data.frame. Defaulting to continuous.
Error in is.finite(x) : default method not implemented for type 'list'

还有其他方法可以完成这个任务吗?

我建议 facets 而不是多个图。但是,要做到这一点,我们需要将数据从“宽”格式转换为“长”格式,而 tidyverse 中的规范方法是 tidyr::pivot_longer.

> basePlot
# A tibble: 53,940 x 8
   carat cut       depth table price     x     y     z
   <dbl> <ord>     <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1 0.23  Ideal      61.5    55   326  3.95  3.98  2.43
 2 0.21  Premium    59.8    61   326  3.89  3.84  2.31
 3 0.23  Good       56.9    65   327  4.05  4.07  2.31
 4 0.290 Premium    62.4    58   334  4.2   4.23  2.63
 5 0.31  Good       63.3    58   335  4.34  4.35  2.75
 6 0.24  Very Good  62.8    57   336  3.94  3.96  2.48
 7 0.24  Very Good  62.3    57   336  3.95  3.98  2.47
 8 0.26  Very Good  61.9    55   337  4.07  4.11  2.53
 9 0.22  Fair       65.1    61   337  3.87  3.78  2.49
10 0.23  Very Good  59.4    61   338  4     4.05  2.39
# ... with 53,930 more rows
> pivot_longer(basePlot, -cut, names_to="var", values_to="val")
# A tibble: 377,580 x 3
   cut     var      val
   <ord>   <chr>  <dbl>
 1 Ideal   carat   0.23
 2 Ideal   depth  61.5 
 3 Ideal   table  55   
 4 Ideal   price 326   
 5 Ideal   x       3.95
 6 Ideal   y       3.98
 7 Ideal   z       2.43
 8 Premium carat   0.21
 9 Premium depth  59.8 
10 Premium table  61   
# ... with 377,570 more rows

有了这个,我们只需要告诉 ggplot2 为值担心 val,为 x-axis 担心 var

library(ggplot2)
library(tidyr) # pivot_longer

ggplot(pivot_longer(basePlot, -cut, names_to="var", values_to="val"),
       aes(cut, val, color=cut)) +
  geom_boxplot(outlier.colour="black", outlier.shape=16, outlier.size=1, notch=FALSE) +
  xlab("Diamond Cut") +
  facet_wrap(~var, nrow=2, scales="free") +
  scale_x_discrete(guide=guide_axis(n.dodge=2))

你在 x-axis 和图例中都有 cut 的原因是因为 color= 将添加图例。由于它是多余的,我们可以删除颜色美学(这也会删除图例)或者我们可以只抑制图例(通过添加 + scale_color_discrete(guide=FALSE))。

分面有两种方式:facet_wrapfacet_grid。后者针对多个变量(x 上的一个方面变量,y 上的一个方面变量)和许多其他配置进行了很好的调整。当然,您可以将 facet_grid 与一个变量一起使用(类似于 facet_wrap(nrow=1)ncol=1),但它们之间存在一些样式差异。