Displaying stat_summary within each group, by aesthetic mapping, in ggplot

Dav*_*veM 5 grouping r ggplot2

我即将绘制出我想要的图,但还没有完全弄清楚是否stat_summary是显示所需图的正确方法。

所需的输出是每个类别内每年具有中线的散点图。例如,在下图中,我想要 A 类中的 1999 年、2000 年和 2001 年的值有一条中线(即按颜色划分的 3 条线),然后 B 类中的值也有一条中线(因此总共 6 条中线)。

我看了这里,但这似乎没有达到我想要的,因为它使用的是方面。

我的图看起来像是在每个类别的中位数之间画一条线。可以stat_summary只在每个类别内绘制一条中线,还是需要使用不同的方法(例如计算中位数并按类别将每条线添加到图中?

在此输入图像描述

可重现的简单示例

library(tidyverse)
library(lubridate)

# Sample data
Date     <- sort(sample(seq(as.Date("1999-01-01"), as.Date("2002-01-01"), by = "day"), 500))
Category <- rep(c("A", "B"), 250)
Value    <- sample(100:500, 500, replace = TRUE)

# Create data frame
mydata   <- data.frame(Date, Category, Value)

# Plot by category and color by year
p <- ggplot(mydata, aes(x = Category, y = Value,
                        color = factor(year(Date))
                        )
            ) + 
  geom_jitter() 
p


# Now add median values of each year for each group
p <- p +
  stat_summary(fun.y = median,
               geom  = "line",
               aes(color = factor(year(Date))),
               group = 1,
               size = 2
               )
p
Run Code Online (Sandbox Code Playgroud)

cam*_*lle 5

您正在寻找的实际上是一个点,即使它看起来像一条线,因为您不想连接观察结果(线的作用),您只想显示一个离散值(点的作用)。

一种方法与您链接的帖子非常相似,就是stat_summary使用基本上是一个大破折号的形状。我调低了抖动点的 Alpha 和大小,以便更好地将它们与中值区分开来。对于中位数,我保持颜色分配相同,但将组设置为年份和类别之间的交互,因此将计算出六个不同的中位数。

请注意,我为随机数生成设置了种子,并将结束日期更改为 12/31/2001 而不是 1/1/2002,因为您说您预计 3 年,但在一代期间我得到了一些 1/1/ 的观察结果2002年。

library(tidyverse)
library(lubridate)

set.seed(987)
Date     <- sort(sample(seq(as.Date("1999-01-01"), as.Date("2001-12-31"), by = "day"), 500))
Category <- rep(c("A", "B"), 250)
Value    <- sample(100:500, 500, replace = TRUE)

# Create data frame
mydata   <- data.frame(Date, Category, Value)

mydata <- mydata %>%
  mutate(year = year(Date) %>% as.factor())

ggplot(mydata, aes(x = Category, y = Value, color = year)) +
  geom_jitter(size = 0.6, alpha = 0.6) +
  stat_summary(fun.y = median, 
               geom = "point",
               aes(group = interaction(Category, year)),
               shape = 95, size = 12, show.legend = F)
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v0.2.0)于 2018-07-01 创建。


Mau*_*ers 3

这是使用geom_errorbar( 而不是stat_summary)的另一种可能性

# Sample data
set.seed(2017);
Date     <- sort(sample(seq(as.Date("1999-01-01"), as.Date("2002-01-01"), by = "day"), 500))
Category <- rep(c("A", "B"), 250)
Value    <- sample(100:500, 500, replace = TRUE)
mydata   <- data.frame(Date, Category, Value)

mydata %>%
    mutate(colour = factor(year(Date))) %>%
    group_by(Category, year(Date)) %>%
    mutate(Median = median(Value)) %>%
    ggplot(aes(Category, Value, colour = colour)) +
    geom_jitter() +
    geom_errorbar(
        aes(ymin = Median, ymax = Median))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

说明:我们预先计算每个中值Categoryyear(Date)使用 绘制中线geom_errorbar


更新

为了回应您的评论,如果您想用于summarise预先计算中值,您可以将中值存储在单独的data.frame

df <- mydata %>%
    mutate(Year = as.factor(year(Date))) %>%
    group_by(Category, Year) %>%
    summarise(Median = median(Value))

ggplot(mydata, aes(Category, Value, colour = factor(year(Date)))) +
    geom_jitter() +
    geom_errorbar(
        data = df,
        aes(x = Category, y = Median, colour = Year, ymin = Median, ymax = Median))
Run Code Online (Sandbox Code Playgroud)

它不像第一个解决方案那么干净(因为您需要在 中指定所有美学geom_errorbar),但生成的图是相同的。