我正在尝试创建一个非常复杂的情节。结果应为堆叠并分组的条形图,并基于第二个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))
结果应如下所示(画线不基于数据,只是为了澄清):
如何将这条线放入图中?
答案 0 :(得分:2)
问题是您的barplot
适用于类别,而折线图应适用于数值。因此,您必须相应地转换x值。
您首先将XAXIS
转换为一个因数(所有级别如df_long_bar
所示),然后将其转换回数字。由于第二个轴最终仅是注解,因此您必须缩放LINE
使其在 first 轴上正确显示。
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))
答案 1 :(得分:2)
您可以在最终数据框中尝试以下操作:
NA
的数据中忽略geom_line
个值; geom_line
的美观映射添加分组变量; 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函数的默认值。