在ggplot2中绘制多个组的平均值

时间:2018-11-06 21:41:50

标签: r ggplot2

我确定这个问题已经被问过了,但是我很难找到一个可行的解决方案:

我有一个数据帧,该数据帧包括两组,每组5个样本,每个样本具有10个观察值,这些观察值在时间上平均分布。我想将此数据集绘制为一个时间序列,并用两条线链接每个时间点上每个组的平均值。我希望在每个时间点都有一些可变性的度量(例如95%置信区间)。

例如,数据集为:

group_a <- data.frame(runif(50, min=80, max=100), 1:10, rep("a", 10), c(rep("i", 10), rep("ii", 10), rep("iii", 10), rep("iv", 10), rep("v", 10)))

names(group_a) <- c("yvar", "xvar", "group", "sample")

group_b <- data.frame(runif(50, min=60, max=80), 1:10, rep("b", 10), c(rep("vi", 10), rep("vii", 10), rep("viii", 10), rep("ix", 10), rep("x", 10)))

names(group_b) <- c("yvar", "xvar", "group", "sample")

sample_data <- rbind(group_a, group_b)

因此,每个时间点(xvar)都有10个案例(样本)观察值(yvar),平均分为两组(group)。我最想要的答案是以下几种:

require(ggplot2)

p <- ggplot(sample_data, aes(x = xvar, y = yvar)) + geom_line(aes(color = group, linetype = group))

print(p)

哪个会产生类似的内容:

因此该行是按组划分的,但是在每个时间点,它都是垂直于每个个案的,而不是作为平均值。

我正在寻找的东西更像另一个答案Plot time series with ggplot with confidence interval中所建议的东西,但是图形上有多条线,不一定是连续的功能区图。

有人有什么建议吗?我知道这应该真的很简单,但是我对R和ggplot还是比较陌生,显然找不到正确的搜索词(或者缺少真正明显的东西)。非常感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

这是两个变体。我建议您预先计算摘要统计信息,然后将其输入ggplot。

sample_sum <- sample_data %>%
  group_by(xvar, group) %>%
  summarize(mean = mean(yvar),
            sd   = sd(yvar),
            mean_p2sd = mean + 2 * sd,
            mean_m2sd = mean - 2 * sd) %>%
  ungroup()

第一种方法是将均值,均值减去2 SD和均值再加上2 SD收集到同一列中,并用“ stat”标记它是哪个stat,并用yvar存储该值。 (我之所以选择它们,是因为+/- 2 SD捕获了〜95%的正态分布。)然后我们可以在一次geom_line调用中将它们绘制在一起。

p <- ggplot(sample_sum %>%
              gather(stat, yvar, mean, mean_p2sd:mean_m2sd), 
            aes(x = xvar, y = yvar)) + 
  geom_line(aes(color = group, linetype = stat))
p

enter image description here

或者,我们可以将它们分开,并使用geom_ribbon绘制+/- 2 SD区域。

p <- ggplot(sample_sum, aes(x = xvar,  color = group, fill = group)) + 
  geom_ribbon(aes(ymin = mean_m2sd, ymax = mean_p2sd), alpha = 0.1) +
  geom_line(aes(y= mean))

p

enter image description here

答案 1 :(得分:0)

我想你想要这样:

p <- ggplot(sample_data, aes(x = xvar, y = yvar, shape = sample)) + 
geom_line(aes(color = group, linetype = sample))
print(p)

enter image description here

答案 2 :(得分:0)

您可以实现rep()功能来指示每个样本,而不是使用gl()。我认为它可以简化您的专栏。

在这里,使用gl(n = 10, k = 1, length = 50, labels = 1:10)。然后将labels = 1:10的因数设为

#> [1] 1  2  3  4  5  6  7  8  9  10 1  2  3  4  5 
#> [16] 6  7  8  9  10 1  2  3  4  5  6  7  8  9  10
#> [31] 1  2  3  4  5  6  7  8  9  10 1  2  3  4  5 
#> [46] 6  7  8  9  10
#> Levels: 1 2 3 4 5 6 7 8 9 10

只需将其添加到yvar,就可以解决问题。

library(tidyverse)

set.seed(10)
(group_a <-
  data_frame(
    yvar = runif(50, min = 80, max = 100),
    gl = gl(n = 10, k = 1, length = 50, labels = 1:10)
  ))
#> # A tibble: 50 x 2
#>     yvar gl   
#>    <dbl> <fct>
#>  1  90.1 1    
#>  2  86.1 2    
#>  3  88.5 3    
#>  4  93.9 4    
#>  5  81.7 5    
#>  6  84.5 6    
#>  7  85.5 7    
#>  8  85.4 8    
#>  9  92.3 9    
#> 10  88.6 10   
#> # ... with 40 more rows

(group_a_mean <-
  group_a %>%
  group_by(gl) %>% # for each group, calculate mean, standard deviation
  summarise(sample_mean = mean(yvar),
            lower = sample_mean - 1.96 * sd(yvar), # lower CI
            upper = sample_mean + 1.96 * sd(yvar))) # upper CI
#> # A tibble: 10 x 4
#>    gl    sample_mean lower upper
#>    <fct>       <dbl> <dbl> <dbl>
#>  1 1            91.3  82.9  99.8
#>  2 2            87.2  78.5  96.0
#>  3 3            86.0  74.0  98.0
#>  4 4            93.1  85.3 101. 
#>  5 5            86.1  80.6  91.6
#>  6 6            89.1  78.5  99.6
#>  7 7            88.0  72.2 104. 
#>  8 8            88.9  77.0 101. 
#>  9 9            90.3  79.8 101. 
#> 10 10           91.7  83.1 100.

group_b相同

(group_b <-
  data_frame(
    yvar = runif(50, min = 60, max = 80),
    gl = gl(n = 10, k = 1, length = 50, labels = 1:10)
  ))
#> # A tibble: 50 x 2
#>     yvar gl   
#>    <dbl> <fct>
#>  1  67.1 1    
#>  2  78.7 2    
#>  3  64.9 3    
#>  4  69.5 4    
#>  5  63.8 5    
#>  6  71.7 6    
#>  7  69.2 7    
#>  8  69.3 8    
#>  9  68.0 9    
#> 10  70.1 10   
#> # ... with 40 more rows

group_b_mean <-
  group_b %>%
  group_by(gl) %>%
  summarise(sample_mean = mean(yvar),
            lower = sample_mean - 1.96 * sd(yvar),
            upper = sample_mean + 1.96 * sd(yvar))

此后,如果两个数据帧与每个组标识符绑定在一起,例如"a""b",则可以绘制所需的内容。

group_a_mean %>%
  mutate(gr = "a") %>% # "a" indicator
  bind_rows(group_b_mean %>% mutate(gr = "b")) %>% # "b" indicator and bind row
  ggplot() +
  aes(x = as.numeric(gl), colour = gr) + # since gl variable is factor, you should conduct as.numeric()
  geom_line(aes(y = sample_mean)) +
  geom_line(aes(y = lower), linetype = "dashed") +
  geom_line(aes(y = upper), linetype = "dashed")

enter image description here

您也可以使用geom_ribbon()

group_a_mean %>%
  mutate(gr = "a") %>%
  bind_rows(group_b_mean %>% mutate(gr = "b")) %>%
  ggplot() +
  aes(x = as.numeric(gl), colour = gr) +
  geom_ribbon(aes(ymin = lower, ymax = upper, fill = gr), alpha = .3) +
  geom_line(aes(y = sample_mean))

enter image description here