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)
您正在寻找的实际上是一个点,即使它看起来像一条线,因为您不想连接观察结果(线的作用),您只想显示一个离散值(点的作用)。
一种方法与您链接的帖子非常相似,就是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 创建。
这是使用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)
说明:我们预先计算每个中值Category并year(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),但生成的图是相同的。