简体   繁体   中英

How to implement stacked bar graph with a line chart in R

I have a dataset containing y variable as Year and x variables as (A, B, C(%)) . I have attached the dataset here .

dput(result)
structure(list(Year = 2008:2021, A = c(4L, 22L, 31L, 48L, 54L, 
61L, 49L, 56L, 59L, 85L, 72L, 58L, 92L, 89L), B = c(1L, 2L, 6L, 
7L, 14L, 21L, 15L, 27L, 27L, 46L, 41L, 26L, 51L, 62L), C... = c(25, 
9.09, 19.35, 14.58, 25.93, 34.43, 30.61, 48.21, 45.76, 54.12, 
56.94, 44.83, 55.43, 69.66)), class = "data.frame", row.names = c(NA, 
-14L))

在此处输入图像描述

The variables A and B will be plotted as stacked bar graph and the C will be plotted as line chart in the same plot. I have generated the plot using excel like below:

在此处输入图像描述

How can I create the same plot in R?

You first need to reshape longer, for example with pivot_longer() from tidyr , and then you can use ggplot2 to plot the bars and the line in two separate layers. The fill = argument in the geom_bar(aes()) lets you stratify each bar according to a categorical variable - name is created automatically by pivot_longer() .

library(ggplot2)
library(tidyr)

dat |> 
  pivot_longer(A:B) |> 
  ggplot(aes(x = Year)) +
  geom_bar(stat = "identity", aes(y = value, fill = name)) +
  geom_line(aes(y = `C(%)`), size = 2)

Created on 2022-06-09 by the reprex package (v2.0.1)

You're asking for overlaid bars, in which case there's no need to pivot, and you can add separate layers. However I would argue that this could confuse or mislead many people - usually in stacked plots bars are stacked, not overlaid, so thread with caution!

library(ggplot2)
library(tidyr)

dat |> 
  ggplot(aes(x = Year)) +
  geom_bar(stat = "identity", aes(y = A), fill = "lightgreen") +
  geom_bar(stat = "identity", aes(y = B), fill = "red", alpha = 0.5) +
  geom_line(aes(y = `C(%)`), size = 2) +
  labs(y = "", caption = "NB: bars are overlaid, not stacked!")

Created on 2022-06-09 by the reprex package (v2.0.1)

I propose this:

library(data.table)
library(ggplot2)
library(ggthemes) 

dt <- fread("dataset.csv")
dt.long <- melt(dt, id.vars = c("Year"))
dt.AB <- dt.long[variable %in% c("A", "B"), ]
dt.C <- copy(dt.long[variable == "C(%)", .(Year, variable, value = value * 3/2)])

ggplot(dt.AB, aes(x = Year, y = value, fill = variable), ) +
  geom_bar(stat = "identity") +
  geom_line(data=dt.C, colour='red', aes(x = Year, y = value)) +
  scale_x_continuous(breaks = pretty(dt.AB$Year, 
                                     n = length(unique(dt.AB$Year)))) +
  scale_y_continuous(
    name = "A&B",
    breaks = seq (0, 150, 10),
    sec.axis = sec_axis(~.*2/3, name="C(%)", breaks = seq (0, 100, 10))
  ) + theme_hc() + 
  scale_fill_manual(values=c("grey70", "grey50", "grey30")) +
  theme( 
    axis.line.y = element_line(colour = 'black', size=0.5, 
                               linetype='solid'))

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM