ggplot,y表示平均值,没有中间数据

时间:2017-02-02 03:34:14

标签: r ggplot2

需要帮助ggplot绘制y轴的平均值并返回带有点的线图以及每个点的文本标签(使用ggplot功能),这些标签按照相应的“颜色”对象参数进行颜色编码。我尽可能不想从原始数据创建任何中间数据框来为y表示创建摘要。我尝试使用fun.y,如代码片段所示。还附有Excel图表。

示例数据

set.seed(1)
age_range = sample(c("ar2-15", "ar16-29", "ar30-44"), 20, replace = TRUE)
gender = sample(c("M", "F"), 20, replace = TRUE)
region = sample(c("A", "B", "C"), 20, replace = TRUE)
physi = sample(c("Poor", "Average", "Good"), 20, replace = TRUE)
height = sample(c(4,5,6), 20, replace = TRUE)
survey = data.frame(age_range, gender, region,physi,height)

ggplot代码我试过

ggplot(survey, aes(x=age_range, y=height, color=gender)) + stat_summary(fun.y=mean, geom = "point")+geom_line()

输出我

enter image description here

输出我正在寻找

enter image description here

1 个答案:

答案 0 :(得分:1)

跟进@ Sandy的评论,你也可以用类似的方式添加标签,虽然我在这里使用包ggrepel来确保它们不重叠(没有手动编码位置)。对于该位置,您可以通过在美学方面调用mean来阅读y的调用结果,该调用结果为..y..

ggplot(survey, aes(x=age_range, y=height, color=gender, group = gender)) +
  stat_summary(fun.y=mean, geom = "point") +
  stat_summary(fun.y=mean, geom = "line") +
  stat_summary(aes(label = round(..y.., 2)), fun.y=mean, geom = "label_repel", segment.size = 0)

给出

enter image description here

(请注意segment.size = 0是为了确保从标签点开始没有额外的线条。)

截至目前,ggrepel似乎不会仅在一个轴上提供文字位移(请参阅here),因此如果您想要更高精度,则可能需要手动定位标签。

如果您想手动设置标签位置,以下是一种使用dplyr%>%管道的方法,以避免必须保存任何中间data.frame

这里描述了基本思想。要在任何步骤后查看结果,只需在行尾的%>%之前突出显示并运行即可。首先,group_by您要绘制的x位置和分组。使用summarise获取每个的平均值。数据仍为group_byage_rangesummarise一次只汇总一个组)。因此,您可以通过减去平均值来确定哪个组在该点具有更高的平均值。我使用sign只是为了拉动它是正还是负,然后乘以/除以facto得到我想要的间距(在这种情况下,除以10得到间距为0.1)。将该调整添加到平均值以设置您希望标签着陆的位置。然后,将所有内容传递到ggplot,然后像处理其他任何data.frame一样继续。

survey %>%
  group_by(age_range, gender) %>%
  summarise(height = mean(height)) %>%
  mutate(myAdj = sign(height - mean(height)) / 10
         , labelLoc = height + myAdj) %>%
  ungroup() %>%
  ggplot(aes(x = age_range
             , y = height
             , label = round(height, 2)
             , color = gender
             , group = gender
  )) +
  geom_point() +
  geom_line() +
  geom_label(aes(y = labelLoc)
             , show.legend = FALSE)

给出:

enter image description here

这似乎可以实现您的基本目标,但您可能希望在实际用例中使用间距等。