0

我想使用具有特定分位数限制的箱线图来绘制 2 个条件(因子 cond0)的 3 对(因子 x0)。

2个问题是:

  1. 条件 A(红色)有 3 组,但条件 B(蓝色)只有 2 组。由于缺少组 1B,组 1A 的箱线图占据了它在图上的空间(两倍大)。我希望它的宽度与其他宽度一样窄,并且即使它是空的,也能保持缺失组 1B 的空间。

  2. 由于组 3B 只有一个值(因此没有异常值),因此组 3A 的异常值位于该对的中间,而不是与箱线图 3A 对齐。

这些问题会有解决方案吗?

感谢帮助

library(dplyr)
library(ggplot2)

# dataframe
x1 <- rep(1:3, each=60)
y1 <- rnorm(180, rep(c(20,35,50), each=60), 10)
cond1 <- rep("A", each=180)
dat1 <- data.frame(x1, y1, cond1)
dat1$x1 <- as.factor(dat1$x1)
dat1$cond1 <- as.factor(dat1$cond1)
dat1 <- dat1 %>% rename(x0 = x1, y0 = y1, cond0 = cond1)

x2 <- rep(2:3, each = 179, len = 180) ; y2
y2 <- rnorm(180, rep(c(30,60), each=90), 7) ; x2
cond2 <- rep("B", each=180)
dat2 <- data.frame(x2, y2, cond2)
dat2$x2 <- as.factor(dat2$x2)
dat2$cond2 <- as.factor(dat2$cond2)
dat2 <- dat2 %>% rename(x0 = x2, y0 = y2, cond0 = cond2)

dat <- rbind(dat1,dat2) 


# define boxplots limits
dat_boxlim <- function(x) {
  r <- quantile(x, probs = c(0.1, 0.4, 0.5, 0.8, 0.9))
  names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
  r
}

# define outliers limits    
dat_boxout <- function(x) {
  subset(x, x < quantile(x, 0.1) | x > quantile(x, 0.9))  
}

# figure
ggplot(dat, aes(x0, y0, group=interaction(cond0, x0), fill = cond0))+
  stat_summary(fun.data = dat_boxlim, geom = "boxplot", position = position_dodge(0.7), width = 0.5, show.legend = TRUE) +
  stat_summary(fun = dat_boxout, geom = "point", size=2, position = position_dodge(0.7), show.legend = FALSE)

在此处输入图像描述

4

1 回答 1

0

第一个问题通过在 stat_summary geom="boxplot" 中使用 "position = position_dodge2(preserve = "single")" 来解决。

第二个问题使用下面的新公式解决。

整个适当的代码是:

library(dplyr)
library(ggplot2)

# dataframe
x1 <- rep(1:3, each=60)
y1 <- rnorm(180, rep(c(20,35,50), each=60), 10)
cond1 <- rep("A", each=180)
dat1 <- data.frame(x1, y1, cond1)
dat1$x1 <- as.factor(dat1$x1)
dat1$cond1 <- as.factor(dat1$cond1)
dat1 <- dat1 %>% rename(x0 = x1, y0 = y1, cond0 = cond1)

x2 <- rep(2:3, each = 179, len = 180) ; y2
y2 <- rnorm(180, rep(c(30,60), each=90), 7) ; x2
cond2 <- rep("B", each=180)
dat2 <- data.frame(x2, y2, cond2)
dat2$x2 <- as.factor(dat2$x2)
dat2$cond2 <- as.factor(dat2$cond2)
dat2 <- dat2 %>% rename(x0 = x2, y0 = y2, cond0 = cond2)

dat <- rbind(dat1,dat2) 

# define boxplots limits
dat_boxlim <- function(x) {
  r <- quantile(x, probs = c(0.1, 0.4, 0.5, 0.8, 0.9))
  names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
  r
}

# define outliers limits
dat_boxout <- function(x) {
  if (length(x) > 1) {  # or other length if needed (e.g. > 7)
    return(subset(x, x < quantile(x, 0.1) | x > quantile(x, 0.9))) # only for low outliers
  } else {
    return(NA)
  }
} 

# figure
ggplot(dat, aes(x0, y0, group=interaction(cond0, x0), fill = cond0))+
  stat_summary(fun.data = dat_boxlim, geom = "boxplot", position = position_dodge2(preserve = "single", 0.7, padding = 0.1), width = 0.5, show.legend = TRUE) +
  stat_summary(fun = dat_boxout, geom = "point", size=2, position = position_dodge(preserve = "total", 0.5), show.legend = FALSE)

在此处输入图像描述

于 2022-01-20T10:58:36.510 回答