如何在R中创建分组箱线图?

24
我希望将三个数据集合并,并获得仅有两个框的图表,1个代表A,1个代表B。您能建议如何实现吗?
我正在尝试在R中创建分组箱线图。我有2个组:A和B,在每个组中,我有3个子组,每个子组有5个测量值。
以下是我构建箱线图的方法,但如果有更好、更短或更容易的方法,请告诉我,谢谢。
A1 <- c(1,2,9,6,4)
A2 <- c(5,1,9,2,3)
A3 <- c(1,2,3,4,5)
B1 <- c(2,4,6,8,10)
B2 <- c(0,3,6,9,12)
B3 <- c(1,1,2,8,7)

DF <- data.frame(A1, A2, A3, B1, B2, B3)

boxplot(DF, col = rainbow(3, s = 0.5))
axis(side = 1, at = c(2,5), labels = c("A","B"))
legend("topleft", fill = rainbow(3, s = 0.5), legend = c(1,2,3), horiz = T)

enter image description here

我该如何正确地将A和B中的方框(联合)分组,并将轴标题固定为简单的A和B,就像我尝试过的那样?

我想要的是类似于:

enter image description here

3个回答

29

当数据以长格式而不是宽格式存在时,像这样分组会更容易。从您的向量开始:

DF2 <- data.frame(
  x = c(c(A1, A2, A3), c(B1, B2, B3)),
  y = rep(c("A", "B"), each = 15),
  z = rep(rep(1:3, each=5), 2),
  stringsAsFactors = FALSE
)
str(DF2)
# 'data.frame': 30 obs. of  3 variables:
#  $ x: num  1 2 9 6 4 5 1 9 2 3 ...
#  $ y: chr  "A" "A" "A" "A" ...
#  $ z: int  1 1 1 1 1 2 2 2 2 2 ...

cols <- rainbow(3, s = 0.5)
boxplot(x ~ z + y, data = DF2,
        at = c(1:3, 5:7), col = cols,
        names = c("", "A", "", "", "B", ""), xaxs = FALSE)
legend("topleft", fill = cols, legend = c(1,2,3), horiz = T)

使用at手动控制位置,因此"视觉分组"不是非常稳健。(您可以使用width和/或boxwex控制它们之间的间距。)

base R boxplot

你也可以选择 ggplot2

library(ggplot2)
ggplot(DF2, aes(y, x, fill=factor(z))) +
  geom_boxplot()

ggplot boxplot


在第一次尝试绘制箱线图时,您如何使坐标轴加粗? - Perro
这并不是加粗的,至少我没有明确地做任何操作。可能是与 ggplot2 不同的默认字体族或其他原因导致的。 - r2evans

3

您应该使用ggplot2

ggplot() + 
  geom_boxplot(data = df, mapping = aes(col_name, value, fill=index))  + 
  theme( axis.text.x = element_blank()) +
  geom_segment(data=hline1, mapping=aes(x=1, y=-0.5, xend=3, yend=-0.5), size=2) +
  annotate("text", x = 2, y = -1, label = "A") + 
  geom_segment(data=hline1, mapping=aes(x=4, y=-0.5, xend=6, yend=-0.5), size=2) +
  annotate("text", x = 5, y = -1, label = "B")

enter image description here


3
使用基本的R语言,我认为@r2evans的解决方案是最好的。然而,对于问题中代码的一个更简单的修复方法是使用选项xaxt="n":
boxplot(DF, col = rainbow(3, s = 0.5), at = c(1:3,5:7), xaxt = "n")
axis(side = 1, at = c(2,6), labels = c("A","B"))
legend("topleft", fill = rainbow(3, s = 0.5), legend = c(1,2,3), horiz = T)

这增加了在格式化轴时的灵活性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接