ggplot2: add line for average per group

后端 未结 2 405
天涯浪人
天涯浪人 2020-12-05 07:10
library(ggplot2)

orderX <- c(\"A\" = 1, \"B\" = 2, \"C\" = 3)
y <- rnorm(20)
x <- as.character(1:20)
group <- c(rep(\"A\", 5), rep(\"B\", 7), rep(\"C\",         


        
相关标签:
2条回答
  • 2020-12-05 07:49

    From your question, I don't this df$x is relevant to your data at all, especially if you can re-order it. How about just using group as x, and jitter the actual x position to separate the points:

    ggplot(data=df, aes(x=group,y=y,color=group)) + geom_point() +
    geom_jitter(position = position_jitter(width = 0.4)) +
    geom_errorbar(stat = "hline", yintercept = "mean",
      width=0.8,aes(ymax=..y..,ymin=..y..))
    

    I have used errorbar instead of h_line (and collapsed the ymax and ymin to y) since hline is complex. If anyone has a better solution to that part, I'd love to see.

    alt text


    update

    If you want to preserve the order of X, try this solution (with modified X)

    df$x = factor(df$x)
    
    ggplot(data = df, aes(x, y, group=group)) + 
    facet_grid(.~group,space="free",scales="free_x") + 
    geom_point() + 
    geom_line(stat = "hline", yintercept = "mean")
    

    alt text

    0 讨论(0)
  • 2020-12-05 07:56

    As of ggplot2 2.x this approach is unfortunately broken.

    The following code provides exactly what I wanted, with some extra calculations up front:

    library(ggplot2)
    library(data.table)
    
    orderX <- c("A" = 1, "B" = 2, "C" = 3)
    y <- rnorm(20)
    x <- as.character(1:20)
    group <- c(rep("A", 5), rep("B", 7), rep("C", 5), rep("A", 3))
    dt <- data.table(x, y, group)
    dt[, lvls := as.numeric(orderX[group])]
    dt[, average := mean(y), by = group]
    dt[, x := reorder(x, lvls)]
    dt[, xbegin := names(which(attr(dt$x, "scores") == unique(lvls)))[1], by = group]
    dt[, xend := names(which(attr(dt$x, "scores") == unique(lvls)))[length(x)], by = group]
    
    ggplot(data = dt, aes(x=x, y=y)) + 
        geom_point(aes(colour = group)) +
        facet_grid(.~group,space="free",scales="free_x") + 
        geom_segment(aes(x = xbegin, xend = xend, y = average, yend = average, group = group, colour = group))
    

    The resulting image:

    0 讨论(0)
提交回复
热议问题