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

bwitn5fc  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(146)

我试着画出这些不同的组,并用一条线连接每组中每个系列(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))

我也发现了一个非常相似的问题here的答案,但我不能得到这个解决方案为我工作。我得到一个错误消息时,运行第二部分(错误geom_line():问题,而计算美学。错误发生在第4层。由于错误FUN():!对象'系列'未找到)
在这一点上,我也很乐意接受任何类型的变通方案,但不能拿出它自己。谢谢!

ilmyapht

ilmyapht1#

这与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

hsvhsicv

hsvhsicv2#

基本上,这是对您在案例中引用的答案中的方法的改编,该方法使用了“手动匀光”,这意味着计算x(当然还有y)。手动为您的中线定位。为此,我们首先必须将Map到x上的sex列转换为数字。其次,我们必须根据series来移动位置(并且当然考虑到width,通过该width来避开箱形图和点),即,对于组A,我们将位置向左移动,而对于组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

相关问题