rggplot2geom-col

How do I create a clustered chart using position dodge in R


I am trying to create a clustered bar graph using ggplot to plot "accum_sum_per" and "mean_per".

The table looks as follows:

DECL_PERIO  accum_sum_per mean_per Years
  <chr>            <dbl>    <dbl> <dbl>
1 2011-2015         0.385    0.366  2015
2 2016              0.404    0.370  2016
3 2017              0.418    0.375  2017
4 2018              0.427    0.383  2018

The code I used to create the graph:

KBA_graph_mean <-
  ggplot(position = "dodge")+
  geom_col(data = sum_KBA_20, aes(x = Years, y=accum_sum_per, fill= "Percentage",)) + 
  geom_col(data = sum_KBA_20, aes(x = Years, y=mean_per, fill="Mean Percentage"))+
  geom_col(position = "dodge")+
  scale_y_continuous(labels=scales::percent) +
  labs(y = "Percentage", x ="Declaration period")+
  theme(legend.position="right",
        legend.title=element_blank())

However, the position function is not taking and my graph is still showing as a stack graph. I tried coding the position in the aes for both geom_col but then I get a warning message stating: "1: Ignoring unknown aesthetics: position 2: Ignoring unknown aesthetics: position"

I would like the bars to be next to each other and not stacked as shown in the graph.

enter image description here


Solution

  • To achieve your desired result reshape your data to long or tidy format. Afterwards it's pretty straight forward to create your dodged barchart as you have one column to be mapped on fill and one column to be mapped on y:

    
    library(ggplot2)
    library(tidyr)
    
    sum_KBA_20_long <- sum_KBA_20 |>
      pivot_longer(c(accum_sum_per, mean_per), names_to = "stat", values_to = "value")
    
    ggplot(sum_KBA_20_long, aes(Years, value, fill = stat)) +
      geom_col(position = "dodge") +
      scale_fill_discrete(labels = c("Percentage", "Mean Percentage")) +
      scale_y_continuous(labels = scales::percent) +
      labs(y = "Percentage", x = "Declaration period") +
      theme(
        legend.position = "right",
        legend.title = element_blank()
      )
    

    DATA

    sum_KBA_20 <- structure(list(DECL_PERIO = c("2011-2015", "2016", "2017", "2018"), accum_sum_per = c(0.385, 0.404, 0.418, 0.427), mean_per = c(
      0.366,
      0.37, 0.375, 0.383
    ), Years = 2015:2018), class = "data.frame", row.names = c(
      "1",
      "2", "3", "4"
    ))