如何在R中按组绘制多个箱线图?

8
ID <- 1:10 
group <- c(1,1,1,2,2,2,3,3,3,3)
var1 <- c(6:15) 
var2 <- c(7:16) 
var3 <- c(6:11, NA, NA, NA, NA)
var4 <- c(4:9, NA, NA, NA, NA) 
data <- data.frame(ID, group, var1, var2, var3, var4)

library(dplyr)
 data %>% group_by(group) %>% boxplot(var1, var2)

最后一行并不符合我的期望。想法是在一个图中获得4个箱线图。每个变量需要两个箱线图。也许我需要使用ggplot2?


4
您是指类似于boxplot(value~group+variable, reshape2::melt(data, 1:2))这样的语句(可能需要事先运行install.packages("reshape2"))? - lukeA
3个回答

12

如果你想在同一个图中获得两个变量,那么你需要重新组织数据。这是一个ggplot2的解决方案:

# load library
  library(ggplot2)
  library(tidyr)
  library(ggthemes)


# reorganize data
  df <- gather(data, "ID","group") 

#rename columns 
  colnames(df) <- c("ID","group","var","value")

# plot
  ggplot(data=df) + 
    geom_boxplot( aes(x=factor(group), y=value, fill=factor(var)), position=position_dodge(1)) +
    scale_x_discrete(breaks=c(1, 2, 3), labels=c("A", "B", "C")) +
    theme_minimal() +
    scale_fill_grey() 

输入图像描述

制作具有相同宽度的箱线图是完全不同的问题,这里有一个解决方案,但一个简单的替代方法如下:

# recode column `group` in the `data.frame`.
  df <- transform(df, group = ifelse(group==1, 'A', ifelse(group==2, 'B', "C")))

# plot
  ggplot(data=df) + 
  geom_boxplot( aes(x=factor(var), y=value, fill=factor((var))), position=position_dodge(1)) +
  geom_jitter(aes(x=factor(var), y=value, color=factor((var)))) +
  facet_grid(.~group, scales = "free_x") +
  theme_minimal()+
  scale_fill_grey() +
  theme(axis.text.x=element_blank(),
        axis.title.x=element_blank(),
        axis.ticks=element_blank())

在这里输入图片描述


谢谢您提供这个简单的解决方案。但是,由于我的实际数据集有点复杂,我仍然有一些“样式”问题。 - SDahm
ID <- 1:10 group <- c(1,1,1,2,2,2,3,3,3,3) var1 <- c(6:15) var2 <- c(7:16) var3 <- c(6:11, NA, NA, NA, NA) var4 <- c(4:9, NA, NA, NA, NA) data <- data.frame(ID, group, var1, var2, var3, var4)

载入库

library(ggplot2) library(tidyr)

重新组织数据

df <- gather(data, "ID","group")

重命名列名

colnames(df) <- c("ID","group","var","value")

绘图

ggplot(data=df) + geom_boxplot( aes(x=factor(group), y=value, fill=factor(var))) + geom_jitter(aes(x=factor(group), y=value))
- SDahm

调整盒子之间的间距,它们太靠近了,特别是对于抖动来说

设置所有盒子相同的宽度;由于缺失,第三个块不同

将颜色更改为灰度或黑白图案

将组命名为(1,2,3)-->“A”,“B”,“C”

- SDahm
在这里,您将找到如何制作具有相同宽度的箱线图的解决方案。我已经在我的问题编辑中解决了您提出的其他问题。 - rafa.pereira
谢谢,这看起来非常不错 :) 当我添加geom_jitter时,不幸的是点在箱子外面,我找不到解决办法。我尝试设置宽度或者像你的例子中一样设置position=position_dodge。宽度没有改变任何东西。位置使它在中间一行。 - SDahm
但是在geom_boxplot()的文档中 - 在'Aesthetics'部分,y不在被此函数理解的美学列表中吗? - amsquareb

5
你可以尝试先将数据框(@lukeA提到的)融合,然后使用基础图形。另外,ggplot2lattice也是不错的选择。
library(reshape2)

DF <- melt(data, id.vars = c("ID", "group"), measure.vars = c("var1", "var2"))

boxplot(value ~ group + variable, DF)

在这里输入图片描述

另一种使用 DF 的替代 lattice 代码:

bwplot(~ value | variable + group, data = DF)

另外一种使用 DFggplot2 代码:

ggplot(DF, aes(x = factor(group), y = value, fill = variable)) + geom_boxplot()

0

虽然有点晚了,但我在这里找到了一个很好的基于R语言的解决方案这里

# Create some data, e.g. from https://en.wikipedia.org/wiki/One-way_analysis_of_variance#Example
df <- as.data.frame(matrix(c(6, 8, 13, 8, 12, 9, 4, 9, 11, 5, 11, 8, 3, 6, 7, 4, 8, 12),ncol = 3, byrow = TRUE))
df <- reshape(data = df, direction = "long", idvar=1:3, varying=1:3, sep = "", timevar = "Treatment")
df$Treatment <- as.factor(df$Treatment)
rownames(df) <- NULL

par(mfrow = c(2, 1))
par(mar=c(1,4,4,2) + 0.1) # mar=c(b,l,t,r)
boxplot(V ~ Treatment, data = df, xlab = NULL, xaxt = "n",
        ylab = "V", main = "One-way anova with 3 different levels of one factor")
stripchart(V ~ Treatment,     # Points
           data = df,         # Data
           method = "jitter", # Random noise
           pch = 19,          # Pch symbols
           col = 4,           # Color of the symbol
           vertical = TRUE,   # Vertical mode
           add = TRUE)        # Add it over

par(mar=c(5,4,0,2) + 0.1)
boxplot(V ~ Treatment, data = df, xlab = "Treatment",
        ylab = "V", main = NULL)
stripchart(V ~ Treatment,     # Points
           data = df,         # Data
           method = "overplot", # Random noise
           pch = 19,          # Pch symbols
           col = 4,           # Color of the symbol
           vertical = TRUE,   # Vertical mode
           add = TRUE)        # Add it over
par(mfrow = c(1, 1))

结果: 在此输入图片描述


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