force boxplots from geom_boxplot to constant width

眉间皱痕 提交于 2019-12-04 23:54:52

The problem is due to some cells of factor combinations being not present. The number of data points for all combinations of the levels of cyl and drv can be checked via 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

There are three empty cells. I will add fake data to override the visualization problems.

Check the range of the dependent variable (y-axis). The fake data needs to be out of this range.

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

Create a subset of mpg with the data needed for the plot:

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

Create an index for the empty cells:

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

idx

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

Create three fake lines (with -1 as value for cty):

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

Add the rows to the existing data:

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

Plot:

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.

Just use the facet_grid() function, makes things a lot easier to visualize:

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

See how I switch from x=as.factor(cyl) to x=as.factor(drv).
Once you have done this you can always change the way you want the strips to be displayed and remove margins between the panels... it can easily look like your expected display.
By the way, you don't even need to use the as.factor() before specifying the columns to be used by ggplot(). this again improve the readability of your code.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!