【问题标题】:force boxplots from geom_boxplot to constant width强制箱线图从 geom_boxplot 到恒定宽度
【发布时间】:2013-05-23 03:22:09
【问题描述】:

我正在制作一个箱线图,其中xfill 映射到不同的变量,有点像这样:

ggplot(mpg, aes(x=as.factor(cyl), y=cty, fill=as.factor(drv))) + 
    geom_boxplot()

如上例所示,在不同的x 值下,我的框的宽度会有所不同,因为我没有xfill 值的所有可能组合,所以。

我希望所有框的宽度相同。这可以做到吗(最好不要操纵底层数据框,因为我担心添加假数据会在进一步分析时引​​起我的困惑)?

我的第一个想法是

+ geom_boxplot(width=0.5)

但这无济于事;它为给定的x 因子水平调整整套箱线图的宽度。

This post 几乎 似乎相关,但我不太明白如何将其应用于我的情况。使用+ scale_fill_discrete(drop=FALSE) 似乎不会改变条的宽度。

【问题讨论】:

标签: r ggplot2 boxplot


【解决方案1】:

问题是由于某些因子组合的单元格不存在。可以通过xtabs查看cyldrv级别的所有组合的数据点数:

tab <- xtabs( ~ drv + cyl, mpg)

tab

#    cyl
# drv  4  5  6  8
#   4 23  0 32 48
#   f 58  4 43  1
#   r  0  0  4 21

有三个空单元格。我将添加假数据来覆盖可视化问题。

检查因变量的范围(y 轴)。假数据需要超出这个范围。

range(mpg$cty)
# [1]  9 35

使用绘图所需的数据创建mpg 的子集:

tmp <- mpg[c("cyl", "drv", "cty")]

为空单元格创建索引:

idx <- which(tab == 0, arr.ind = TRUE)

idx

#   row col
# r   3   1
# 4   1   2
# r   3   2

创建三个假行(cty 的值为 -1):

fakeLines <- apply(idx, 1,
                   function(x) 
                     setNames(data.frame(as.integer(dimnames(tab)[[2]][x[2]]), 
                                         dimnames(tab)[[1]][x[1]], 
                                         -1), 
                              names(tmp)))

fakeLines

# $r
#   cyl drv cty
# 1   4   r  -1
# 
# $`4`
#   cyl drv cty
# 1   5   4  -1
# 
# $r
#   cyl drv cty
# 1   5   r  -1

将行添加到现有数据中:

tmp2 <- rbind(tmp, do.call(rbind, fakeLines))

剧情:

library(ggplot2)
ggplot(tmp2, aes(x = as.factor(cyl), y = cty, fill = as.factor(drv))) + 
  geom_boxplot() +
  coord_cartesian(ylim = c(min(tmp$cty - 3), max(tmp$cty) + 3))
  # The axis limits have to be changed to suppress displaying the fake data.

【讨论】:

    【解决方案2】:

    您现在可以使用position_dodge() 函数。

    ggplot(mpg, aes(x=as.factor(cyl), y=cty, fill=as.factor(drv))) + 
        geom_boxplot(position = position_dodge(preserve = "single"))
    

    【讨论】:

      【解决方案3】:

      只需使用facet_grid() 函数,让事情更容易可视化:

      ggplot(mpg, aes(x=as.factor(drv), y=cty, fill=as.factor(drv))) + 
          geom_boxplot() +
          facet_grid(.~cyl)
      

      看看我如何从x=as.factor(cyl) 切换到x=as.factor(drv)
      完成此操作后,您可以随时更改条带的显示方式并删除面板之间的边距......它很容易看起来像您预期的显示。
      顺便说一句,在指定ggplot() 要使用的列之前,您甚至不需要使用as.factor()。这再次提高了代码的可读性。

      【讨论】:

        猜你喜欢
        • 2014-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-28
        • 2019-09-12
        • 2019-03-31
        相关资源
        最近更新 更多