Включите пространство для отсутствия уровня фактора, используемого для эстетики заливки в geom_boxplot

Я пытаюсь нарисовать квадрат и график усов в R. Мой код ниже. На данный момент, поскольку у меня есть только данные за два месяца на одном из двух сайтов, бары шире для этого сайта (поскольку третий уровень месяца отбрасывается).

Вместо этого мне нужна такая же схема ящиков для сайта A, как и для сайта B (т.е. с пробелом для пустого поля справа). Я легко могу сделать это с помощью drop=TRUE, когда у меня есть только один фактор, но, похоже, он не может сделать это с коэффициентом заполнения.

Month=rep(c(rep(c("Jan","Feb"),2),"Mar"),10)
Site=rep(c(rep(c("A","B"),each=2),"B"),10)
factor(Month)
factor(Site)
set.seed(1114)
Height=rnorm(50)
Data=data.frame(Month,Site,Height)
plot = ggplot(Data, aes(Site, Height)) +
       geom_boxplot(aes(fill=Month, drop=TRUE), na.rm=FALSE)
plot

Ответ 1

Одним из способов достижения желаемого результата является изменение данных, полученных при построении графика.

Сначала сохраните объект как объект, а затем используйте ggplot_build(), чтобы сохранить все части данных сюжета в качестве объекта.

p<-ggplot(Data, aes(Site, Height,fill=Month)) + geom_boxplot()
dd<-ggplot_build(p)

Данные элемента списка содержат всю информацию, используемую для построения графика.

dd$data

[[1]]
     fill      ymin      lower     middle      upper      ymax  outliers notchupper notchlower    x PANEL
1 #F8766D -1.136265 -0.2639268  0.1978071  0.5318349 0.9815675            0.5954014 -0.1997872 0.75     1
2 #00BA38 -1.264659 -0.6113666  0.3190873  0.7915052 1.0778202            1.0200180 -0.3818434 1.00     1
3 #F8766D -1.329028 -0.4334205  0.3047065  1.0743448 1.5257798            1.0580462 -0.4486332 1.75     1
4 #00BA38 -1.137494 -0.7034188 -0.4466927 -0.1989093 0.1859752 -1.759846 -0.1946196 -0.6987658 2.00     1
5 #619CFF -2.344163 -1.2108919 -0.5457815  0.8047203 2.3773189            0.4612987 -1.5528617 2.25     1
  group weight ymin_final ymax_final  xmin  xmax
1     1      1  -1.136265  0.9815675 0.625 0.875
2     2      1  -1.264659  1.0778202 0.875 1.125
3     3      1  -1.329028  1.5257798 1.625 1.875
4     4      1  -1.759846  0.1859752 1.875 2.125
5     5      1  -2.344163  2.3773189 2.125 2.375

Вас интересуют значения x, xmax и xmin. Первые две строки соответствуют уровню A. Эти значения следует изменить.

dd$data[[1]]$x[1:2]<-c(0.75,1)
dd$data[[1]]$xmax[1:2]<-c(0.875,1.125)
dd$data[[1]]$xmin[1:2]<-c(0.625,0.875)

Теперь используйте ggplot_gtable() и grid.draw() для печати измененных данных.

library(grid)
grid.draw(ggplot_gtable(dd))

enter image description here

Ответ 2

Вот решение, основанное на создании поддельных данных:

Во-первых, новая строка добавляется в фрейм данных. Он содержит точку данных для несуществующей комбинации уровней факторов (Mar и A). Значение Height должно находиться вне диапазона реальных Height данных.

Data2 <- rbind(Data, data.frame(Month = "Mar", Site = "A", Height = 5))

Затем график может быть сгенерирован. Поскольку поддельные данные не должны быть видимыми, ограничения оси y должны быть изменены с помощью coord_cartesian и диапазона исходных данных Height.

library(ggplot2)
ggplot(Data2, aes(Site, Height)) +
  geom_boxplot(aes(fill = Month)) +
  coord_cartesian(ylim = range(Data$Height) + c(-.25, .25))

enter image description here