我正在制作一个箱形图,其中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
因子级别的整套箱图的宽度。
This post 几乎似乎相关,但我不太清楚如何将其应用于我的情况。使用+ scale_fill_discrete(drop=FALSE)
似乎不会改变条形的宽度。
答案 0 :(得分:1)
问题是由于某些因子组合的细胞不存在。可以通过cyl
检查drv
和xtabs
级别的所有组合的数据点数量:
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.
答案 1 :(得分:0)