R 强制箱线图从geom_箱线图变为恒定宽度

R 强制箱线图从geom_箱线图变为恒定宽度,r,ggplot2,boxplot,R,Ggplot2,Boxplot,我正在做一个方框图,其中x和fill映射到不同的变量,有点像这样: ggplot(mpg, aes(x=as.factor(cyl), y=cty, fill=as.factor(drv))) + geom_boxplot() 如上例所示,在不同的x值下,我的框的宽度会有所不同,因为我没有x和fill值的所有可能组合,所以 我希望所有的盒子都是一样的宽度。这可以做到吗(理想情况下不操纵底层数据框架,因为我担心添加虚假数据会在进一步分析过程中造成混乱) 我的第一个想法是 + geom

我正在做一个方框图,其中
x
fill
映射到不同的变量,有点像这样:

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

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

我希望所有的盒子都是一样的宽度。这可以做到吗(理想情况下不操纵底层数据框架,因为我担心添加虚假数据会在进一步分析过程中造成混乱)

我的第一个想法是

+ geom_boxplot(width=0.5)
但这没有帮助;它为给定的
x
因子水平调整全套箱线图的宽度


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

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

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
使用绘图所需的数据创建一个子集
mpg

tmp <- mpg[c("cyl", "drv", "cty")]
将行添加到现有数据:

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

只需使用
facet\u 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()
。这再次提高了代码的可读性。

这是否回答了您的问题?
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.
ggplot(mpg, aes(x=as.factor(drv), y=cty, fill=as.factor(drv))) + 
    geom_boxplot() +
    facet_grid(.~cyl)