繁体   English   中英

在ggplot中连接嵌套组内的中位数?

[英]Connect medians within nested groups in ggplot?

我正在尝试 plot 这些不同的组,并用一条线连接每个组内每个系列(A、B、C)的中位数。

    n <- 60
    data <- data.frame(series=rep(LETTERS[1:3], n/3), 
                   sex=rep(c("F","M"),each=30), 
                   setting=rep(c("wild","rural"),n/2),
                   fit=rnorm(n))

    ggplot(data,aes(x=sex, y=fit, fill=series)) +
    geom_boxplot(width=.3,aes( alpha=.5,color=sex),
              lwd=0.8, position = position_dodge(width = 0.6)) + 
    facet_grid(~setting) +
    stat_summary(fun.y=median, geom="point", shape=23, size=2,
               position=position_dodge(width = 0.6)) +
    geom_text(aes(y=-2.5, label=series),  position=position_dodge(width=0.6)) +

    geom_point(shape=20,alpha=0.2,position=position_jitterdodge(dodge.width = 0.6,jitter.width = 0.25))+
    theme_blank()

到目前为止,这是它的样子——

我一直在玩弄 geom_line 和 stats_summary,但不是很成功,因为分组似乎总是错误的。 这是我尝试使用 stats_summary 的示例,看起来像我真正想要的 4 条线(在每组中将 A 连接到 C),但由于某种原因没有被箱线图覆盖......

    stat_summary(fun.y=median, colour="red", geom="line",aes(x=series, group=interaction(setting,sex)),
             position=position_dodge(width = 0.6))

我在这里也找到了一个非常相似的已回答问题,但我无法让这个解决方案为我工作。 我在运行第二部分时收到一条错误消息( geom_line()中的错误:计算美学时出现问题。ℹ 错误发生在第 4 层。由FUN()中的错误引起:!object 未找到“系列”)

在这一点上,我也很乐意接受任何类型的解决方法,但我自己想不出。 谢谢!

基本上,这是对您引用的案例答案中的方法的改编,它使用“手动躲避”,这意味着计算x (当然还有y )。 手动定位中线。 为此,我们首先必须将映射到x上的sex列转换为数字。 其次,我们必须根据series移动位置(当然要考虑到您躲避箱形图和点的width ),即对于 A 组,我们将 position 向左移动,对于组 C 向右移动。

set.seed(123)

library(ggplot2)
library(dplyr)

data_line <- data %>%
  group_by(setting, sex, series) %>%
  summarise(fit = median(fit)) |>
  ungroup() |> 
  # Manual dodging 
  mutate(x_num = as.numeric(factor(sex)) + seq(-1, 1, length.out = 3) * .6 / 3)
#> `summarise()` has grouped output by 'setting', 'sex'. You can override using
#> the `.groups` argument.

ggplot(data, aes(x = sex, y = fit, fill = series)) +
  geom_boxplot(
    width = .3, aes(alpha = .5, color = sex),
    lwd = 0.8, position = position_dodge(width = 0.6)
  ) +
  facet_grid(~setting) +
  stat_summary(
    fun = median, geom = "point", shape = 23, size = 2,
    position = position_dodge(width = 0.6)
  ) +
  geom_line(data = data_line,
    aes(x = x_num, group = sex),
    colour = "red"
  )+
  geom_text(aes(y = -2.5, label = series), position = position_dodge(width = 0.6)) +
  geom_point(shape = 20, alpha = 0.2, position = position_jitterdodge(dodge.width = 0.6, jitter.width = 0.25))
#> Warning: `position_dodge()` requires non-overlapping x intervals
#> `position_dodge()` requires non-overlapping x intervals

这与 Stefan 的方法类似,但计算是在 ggplot 中即时完成的:

library(ggplot2)

n <- 60
data <- data.frame(series=rep(LETTERS[1:3], n/3), 
                   sex=rep(c("F","M"),each=30), 
                   setting=rep(c("wild","rural"),n/2),
                   fit=rnorm(n))

ggplot(data, aes(x = as.numeric(interaction(series, sex)) +
                   1.5 * ((as.numeric(interaction(series, sex)) - 1) %/% 3), 
                 y = fit, fill = series)) +
  geom_boxplot(width = 0.5, aes(color = sex), alpha = 0.5) + 
  geom_point(fun = median, stat = "summary", shape = 23, size = 2) +
  geom_text(aes(y = -2.5, label = series)) +
  geom_point(shape = 20, alpha = 0.2, position = position_jitter(0.25)) +
  geom_line(stat = "summary", fun = median, aes(group = sex)) +
  facet_grid(~setting) +
  scale_x_continuous(NULL, breaks = c(2, 6.5), labels = c("F", "M"),
                     limits = c(0, 8.5)) +
  ggnetwork::theme_blank() +
  theme(axis.text.x.bottom = element_text(), strip.background = element_blank())

创建于 2022-12-14,使用reprex v2.0.2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM