我确定这个问题已经被问过了,但是我很难找到一个可行的解决方案:
我有一个数据帧,该数据帧包括两组,每组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还是比较陌生,显然找不到正确的搜索词(或者缺少真正明显的东西)。非常感谢您的帮助!
答案 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
或者,我们可以将它们分开,并使用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
答案 1 :(得分:0)
我想你想要这样:
p <- ggplot(sample_data, aes(x = xvar, y = yvar, shape = sample)) +
geom_line(aes(color = group, linetype = sample))
print(p)
答案 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")
您也可以使用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))