К сожалению, первый ответ по метке (до редактирования) содержал серьезный недостаток, из-за которого столбцы, показывающие остатки , были в два раза выше ожидаемых . Это станет сразу видно, когда заполнение столбцов будет окрашено в соответствии с key
:
library(dplyr)
library(tidyr)
library(ggplot2)
data_frame(time, a, b) %>%
mutate(diff_a_b = a - b) %>%
gather(key, value, a, b) %>%
ggplot(., aes(time)) +
geom_line(aes(y = value, color = key)) +
geom_col(aes(y = diff_a_b, fill = key))
Основная причина в том, что diff_a_b
не обрабатывается как переменная при изменении формы с широкого на длинный формат:
data_frame(time, a, b) %>%
mutate(diff_a_b = a - b) %>%
gather(key, value, a, b)
Итак, diff_a_b
появляется дважды для каждого time
значения:
# A tibble: 20 x 4
time diff_a_b key value
<date> <dbl> <chr> <dbl>
1 1999-06-15 0.3 a 22.3
2 2000-06-15 -0.800 a 24.1
3 2001-06-15 4 a 35
4 2002-06-15 1 a 35
5 2003-06-15 -1.6 a 35.9
6 2004-06-15 2.9 a 39.2
7 2005-06-15 2.70 a 34.8
8 2006-06-15 1.8 a 31.5
9 2007-06-15 0.5 a 29.1
10 2008-06-15 1.9 a 25.8
11 1999-06-15 0.3 b 22
12 2000-06-15 -0.800 b 24.9
13 2001-06-15 4 b 31
14 2002-06-15 1 b 34
15 2003-06-15 -1.6 b 37.5
16 2004-06-15 2.9 b 36.3
17 2005-06-15 2.70 b 32.1
18 2006-06-15 1.8 b 29.7
19 2007-06-15 0.5 b 28.6
20 2008-06-15 1.9 b 23.9
В качестве значения по умолчанию для geom_col()
установлено значение position = "stack"
, два значения накладываются друг на друга.
Быстрые исправления для ответа Маркуса
Если позиция меняется на "dodge"
, тогда ответ Маркуса покажет ожидаемый результат
data_frame(time, a, b) %>%
mutate(diff_a_b = a - b) %>%
gather(key, value, a, b) %>%
ggplot(., aes(time)) +
geom_line(aes(y = value, color = key)) +
geom_col(aes(y = diff_a_b), position = "dodge")
Другим исправлением будет использование geom_linerange()
, где каждый сегмент будет нанесен дважды:
data_frame(time, a, b) %>%
mutate(diff_a_b = a - b) %>%
gather(key, value, a, b) %>%
ggplot(., aes(time)) +
geom_line(aes(y = value, color = key)) +
geom_linerange(aes(ymin = 0, ymax = diff_a_b), size = 3)
"Tidy" подход
ИМХО, правильный ("аккуратный") подход - обрабатывать diff_a_b
как третью переменную / временной ряд при изменении формы и использовать параметр data
при создании geoms:
data_frame(time, a, b) %>%
mutate(diff_a_b = a - b) %>%
gather(, , -time) %>%
ggplot(aes(x = time, y = value)) +
geom_line(aes(col = key), data = function(x) filter(x, key != "diff_a_b")) +
geom_col(data = function(x) filter(x, key == "diff_a_b"))
data.table
и ggplot2
Для тех, кто предпочитает data.table
для сбора данных:
library(data.table)
library(ggplot2)
long <- data.table(time, a, b)[
, diff_a_b := a - b][
, melt(.SD, "time")]
ggplot() + aes(time, value) +
geom_line(aes(color = variable), data = long[variable != "diff_a_b"]) +
geom_col(data = long[variable == "diff_a_b"])