箱线图 - 在一个箱线图中按两组显示相同的数据

Boxplot - Displaying the same data, by two groups in one box plot

我有一组数据是从两个不同地区的七个不同站点收集的。我想使用箱形图来显示站点之间和区域之间的差异。我目前有两个独立的箱线图。我正在尝试(但没有运气)如何在一个图中显示两者......即我希望我的数字显示结果为: 站点 1、站点 2、站点 3、站点 4.... 区域 1、区域 2 <- 都在一个图中。我在下面提供了示例数据和我当前的代码。您会注意到我的轴翻转了 - 这是故意的,因为我的站点名称比较长。

谢谢!

#Example script

example<-structure(list(Site = c("NS", "NS", "NS", "NE", "NE", "NE", "KO", 
                                 "KO", "KO", "MI", "MI", "MI", "KI", "KI", "KI", "HP", "HP", "HP", 
                                 "HA", "HA", "HA"), Var1 = c(30, 5, 4, 0.3, 0, 0, 48, 79, 43, 
                                                             30, 30, 50, 5, 3, 3, 20, 31, 50, 30, 40, 68), Region = c("A", 
                                                                                                                      "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", 
                                                                                                                      "B", "B", "B", "B", "B", "B", "B")), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                               -21L))
######## By Site
library(forcats)
p <- example %>%
  mutate(Site = fct_relevel(Site, "HA", "HP",
                            "KI", "MI","KO", "NE",
                            "NS"
  )) %>%
  ggplot( aes(x=Site, y=Var1, fill = Region)) +
  geom_boxplot()+xlab("Site") + ylab ("Variable 1") + ylim(0,100) +
  coord_flip() + theme_bw() 
plot1<- p+scale_fill_manual(values=c("#0072B2", "#D55E00")) + theme(axis.text=element_text(size=11),
                                                                    axis.title=element_text(size=12))

plot1
####################### By Regions

example$Region<-factor(example$Region, levels=c("B", "A"))


pplot2<-ggplot(example, aes(x = Region, y = Var1, fill = Region)) + geom_boxplot()
pplot2<-pplot2 + ylab("Variable 1") + ylim (0,100) + 
  scale_x_discrete(limits = rev(levels("Region"))) + coord_flip()+ theme_bw() + scale_fill_manual(values=c("#D55E00", "#0072B2")) + theme(axis.text=element_text(size=11),
                                                                                                                                          axis.title=element_text(size=12))

pplot2

如果只想堆叠地块,可以尝试library(patchwork)。它具有将多个图组合在一起的简单语法。这里有一个tutorial.

library(patchwork)
p3 <- plot1/(pplot2 + theme(legend.position="none"))

如果您真的希望它们共享相同的轴,我有一种 hacky/clunky 解决方案。如果您堆叠数据框以便“区域”也包含在“站点”列中,那么您可以将站点和区域作为同一轴。缺点是这会使标记轴有点笨拙。所以,我玩弄 hjust 并在 lab(x=) 中添加空格以使其正确排列。我还添加了 geom_vline()(因为坐标被翻转)以在视觉上将 region-based 和 site-based 箱线图分开。同样,不是优雅,而是完成工作。

example2 <- example %>% mutate(Site = Region)
dat <- rbind(example, example2)

p4 <- dat %>% mutate(Site = fct_relevel(Site, "HA", "HP",
                                  "KI", "MI","KO", "NE",
                                  "NS", "B", "A"
)) %>% ggplot(aes(x=Site, y=Var1, fill=Region)) + geom_boxplot() + 
  coord_flip() + theme_bw() + scale_fill_manual(values=c("#0072B2", "#D55E00")) + 
  theme(axis.text=element_text(size=11),
        axis.title=element_text(size=12)) + labs(y="Variable 1", 
                                                 x="Site                            Region") + 
  theme(axis.title.y=element_text(hjust=.90)) +
  geom_vline(xintercept = 7.5)

另一种可能性是使用 SiteRegion 将您的数据框转换为长格式,然后绘制:

library(tidyverse)
# get data in long format
example_long <- example %>% 
  pivot_longer(
    cols = c(Site, Region),
    names_to = "names",
    values_to = "values"
  ) %>% 
  mutate(values = fct_relevel(values, "HA", "HP",
                              "KI", "MI","KO", "NE",
                              "NS", "B", "A"
  )) 

# plot
ggplot(example_long, aes(x=values, y=Var1, fill = names)) +
  geom_boxplot()+ 
  xlab("Values") + ylab ("Variable 1") + ylim(0,100) +
  coord_flip() + 
  theme_bw() +
  scale_fill_manual(values=c("#0072B2", "#D55E00")) + theme(axis.text=element_text(size=11),
                                                            axis.title=element_text(size=12)) +
  theme(legend.title = element_blank(),
        axis.title.y = element_blank())