#r #ggplot2
#r #ggplot2
Вопрос:
Я пытаюсь создать довольно сложный график. Результатом должен быть сложенный и сгруппированный столбчатый график с дополнительными линиями на основе второй оси y. До сих пор мне удавалось создать сложенный и сгруппированный столбчатый график (псевдогруппированный, для меня достаточно), но я страдаю при присвоении линейной части второй оси y.
library(tidyverse)
library(magrittr)
df <- data.frame(
DATE = c("2019-01-01", "2019-01-08", "2019-01-15")
, XXX_TY_T = c(20, 30, 25)
, XXX_TY_C = c(10, 5, 15)
, XXX_PY_T = c(15, 20, 20)
, XXX_PY_C = c(20, 20, 15)
, YYYY_TY_TD = c(0.7, 0.8, 0.75)
, YYYY_PY_TD = c(0.4, 0.7, 0.6)
)
df_long <- df %>%
gather(CATEGORY, VALUE, XXX_TY_T:YYYY_PY_TD) %>%
mutate(CATEGORY2 = c(rep("XXX_TY", 6), rep("XXX_PY", 6), rep(NA, 6))
, XAXIS = paste0(DATE, " | ", CATEGORY2))
df_long_bar <- df_long %>% filter(!(CATEGORY %in% c("YYYY_TY_TD", "YYYY_PY_TD")))
df_long_line <- df_long %>% filter(CATEGORY %in% c("YYYY_TY_TD", "YYYY_PY_TD")) %>%
rename(LINE = VALUE) %>%
mutate(CATEGORY2 = ifelse(CATEGORY == "YYYY_TY_TD", "XXX_TY", "XXX_PY")
, XAXIS = paste0(DATE, " | ", CATEGORY2)) %>%
filter(CATEGORY2 == "XXX_PY") %>%
select(XAXIS, LINE)
df_long_plot <- left_join(df_long_bar, df_long_line, by = c("XAXIS"))
ggplot(df_long_plot)
geom_bar(aes(x = XAXIS, y = VALUE, fill = CATEGORY), stat = "identity", position = "stack")
geom_line(aes(x = XAXIS, y = LINE), stat = "identity")
scale_y_continuous(sec.axis = sec_axis(~./40))
Результат должен выглядеть следующим образом (нарисованная линия не основана на данных, просто для уточнения):
Как я могу ввести эту линию в график?
Ответ №1:
Вы можете попробовать следующее с вашим окончательным фреймом данных:
- Исключить
NA
значения из данных, переданных вgeom_line
; - Добавьте группирующую переменную к
geom_line
эстетическим отображениям; - Преобразуйте значение y (используйте преобразование, противоположное тому, которое используется в
sec_axis
).
ggplot(df_long_plot, aes(x = XAXIS)) # put common aes mappings on top
geom_col(aes(y = VALUE, fill = CATEGORY)) # geom_col() is equivalent to
# geom_bar(stat = "identity")
geom_line(data = . %>% na.omit(),
aes(y = LINE * 40, group = 1))
scale_y_continuous(sec.axis = sec_axis(~./40))
Я удалил из кода параметры position = "stack"
/ stat = "identity"
, поскольку в любом случае это значения по умолчанию для соответствующих функций geom.
Ответ №2:
Проблема в том, что ваш barplot
работает с категориями, в то время как ваш линейный график должен работать с числовыми значениями. Таким образом, вы должны соответствующим образом перенести свои значения x.
Сначала вы преобразуете свой XAXIS
коэффициент (со всеми уровнями, как показано в df_long_bar
), а затем преобразуете его обратно в числовой. Поскольку вторая ось, в конечном счете, является простой аннотацией, вы должны масштабировать LINE
так, чтобы она правильно отображалась на первой оси.
ggplot()
geom_bar(data = df_long_bar,
aes(x = XAXIS,
y = VALUE,
fill = CATEGORY),
stat = "identity",
position = "stack")
geom_line(data = df_long_line,
aes(x = as.numeric(factor(XAXIS,
levels(as.factor(df_long_bar$XAXIS)))),
y = LINE * 40))
scale_y_continuous(sec.axis = sec_axis(~ . / 40))