代码之家  ›  专栏  ›  技术社区  ›  yuk

使用ggplot2将组平均线添加到条形图

  •  3
  • yuk  · 技术社区  · 7 年前

    我用geom_col()生成了一个条形图,两个类用颜色分隔。然后我试着为每节课加一条平均线。

    以下是我想要的:

    Desired output

    但是在平均线以下的代码中,每一条都是独立的,就像我对组参数所做的那样。

    下面是一个可重复的示例:

    library(tidyverse)
    
    df = data.frame(
      x = 1:10,
      y = runif(10),
      class = sample(c("a","b"),10, replace=T) %>% factor()
    ) %>% 
      mutate(x = factor(x, levels=x[order(class, -y)]))
    
    ggplot(df, aes(x, y, fill=class)) +
    geom_col() +
    stat_summary(fun.y = mean, geom = "errorbar", 
                 aes(ymax = ..y.., ymin = ..y.., group = class),
                 width = 1, linetype = "solid")
    

    What I get

    请告诉我我做错了什么。或者用其他方法(用ggplot)来实现这个目标?

    2 回复  |  直到 7 年前
        1
  •  2
  •   bouncyball    7 年前

    创建新的 data.frame (添加组平均值)并对其进行一些操作(使用 top_n cbind ,然后使用它们为 geom_segment :

    # add group mean
    df_m <- df %>%
      group_by(class) %>%
      mutate(my = mean(y)) %>%
      arrange(class) # added from comment by @Yuk
    
    # select top and bottom x for each class group
    # use cbind to keep one row per group
    df_m2 <- df_m %>%
      top_n(1, x) %>%
      cbind(top_n(df_m, -1, x))
    
    ggplot(df) +
      geom_col(aes(x, y, fill=class))+
      geom_segment(data = df_m2,
                   aes(x = x, xend = x1,
                       y = my, yend = my1,
                       group = class))
    

    enter image description here

        2
  •  2
  •   yuk    7 年前

    我将@bouncyball的解决方案与使用“geom”errorbar的原始方法结合起来。

    代码如下:

    df.mean = df %>% 
      group_by(class) %>% 
      mutate(ymean = mean(y))
    
    ggplot(df, aes(x, y, fill=class)) +
      geom_col() +
      geom_errorbar(data=df.mean, aes(x, ymax = ymean, ymin = ymean),
                   size=0.5, linetype = "longdash", inherit.aes = F, width = 1)
    

    enter image description here

    唯一的问题是,这种方法生成的线对象不是单行的,而是很多在编辑绘图时可以看到的线对象,例如在adobe illustrator中。但我可以忍受。