【问题标题】:ggplot2: add line for average per groupggplot2:为每组平均添加线
【发布时间】:2011-05-13 18:00:09
【问题描述】:
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", 5), rep("A", 3))
df <- data.frame(x, y, group)
df$lvls <- as.numeric(orderX[df$group])

ggplot(data = df, aes(x=reorder(df$x, df$lvls), y=y)) + 
geom_point(aes(colour = group)) + 
geom_line(stat = "hline", yintercept = "mean", aes(colour = group))

我想创建一个这样的图表:

当我不需要重新排序 X 的值时,这确实有效,但是,当我使用重新排序时,它不再有效。

【问题讨论】:

  • 我认为您在这里使用重新排序是错误的,因为它只会重新排序 X,而不是组或 Y。这将用错误的 y 绘制错误的 x!
  • 除非 X 只表示索引,否则不要在图中使用它(使用 jitter 代替?)
  • 那我对 reorder 的使用是错误的。在我的真实数据中,x 上的值是每个单独测量的标签,我确实希望看到。这些标签在组中的顺序无关紧要。
  • 也许它在我的情况下不起作用的另一个原因是,因为我的 x 值不是数字,而是字符。
  • +1 简洁的问题,带有示例数据和图片。如果可以的话,我会给每个人 +1。

标签: r ggplot2


【解决方案1】:

不幸的是,从 ggplot2 2.x 开始,这种方法被破坏了。

以下代码提供了我想要的内容,并预先进行了一些额外的计算:

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))

生成的图像:

【讨论】:

  • 我不确定这是否会对您的具体情况有所帮助,但我使用 ggplot2 v2.1.0 找到的类似问题的新解决方案是 stat_summary(fun.y = "mean", fun.ymin = "mean", fun.ymax= "mean", size= 0.3, geom = "crossbar")
  • 我试过了,它会在 x 轴上为每个项目创建水平线。原因是 x 轴是离散的。
【解决方案2】:

根据您的问题,我认为 df$x 与您的数据完全不相关,尤其是如果您可以重新排序。不如只用group作为x,用jitter实际的x位置来分隔点:

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..))

由于 hline 很复杂,我使用了 errorbar 而不是 h_line(并将 ymax 和 ymin 折叠到 y)。如果有人对此部分有更好的解决方案,我很乐意看到。


更新

如果你想保留X的顺序,试试这个解决方案(修改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")

【讨论】:

  • 这确实几乎是我想要的,但是,我确实希望能够在 x 尺度上看到原始 x 值。
  • 当您执行上述重新排序时,您的数据会混淆。您应该对原始数据框进行排序,而不仅仅是 x 值。您希望 x 值在图表中交错吗?如果是,你想把平均值放在哪里?
  • 您在哪里找到有关 geom_line(stat="hline", yintercept="mean") 的文档?这真的很酷,我以前从未见过。
  • 我真的不记得了,明天在我的机器上查找它。必须在浏览器历史记录中的某个位置。 :)
猜你喜欢
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 2016-04-21
  • 2019-08-22
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
相关资源
最近更新 更多