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

Time:10-05

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

CodePudding user response:

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"
))

CodePudding user response:

This type of problems generally has to do with reshaping the data. The format should be the long format and the data is in wide format. See this post on how to reshape the data from wide to long format.

suppressPackageStartupMessages({
  library(dplyr)
  library(tidyr)
  library(ggplot2)
})

sum_KBA_20 %>%
  select(-DECL_PERIO) %>%
  pivot_longer(-Years, names_to = "per", values_to = "Percentage") %>%
  ggplot(aes(Years, Percentage, fill = per))  
  geom_col(position = "dodge")  
  scale_fill_manual(name = "Percentage", 
                    labels = c("Percentage", "Mean Percentage"),
                    values = c(accum_sum_per = "red", mean_per = "blue"))

Created on 2022-10-05 with reprex v2.0.2


Data

sum_KBA_20 <- 'DECL_PERIO  accum_sum_per mean_per Years
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'

sum_KBA_20 <- read.table(textConnection(sum_KBA_20), header = TRUE)
str(sum_KBA_20)
#> 'data.frame':    4 obs. of  4 variables:
#>  $ DECL_PERIO   : chr  "2011-2015" "2016" "2017" "2018"
#>  $ accum_sum_per: num  0.385 0.404 0.418 0.427
#>  $ mean_per     : num  0.366 0.37 0.375 0.383
#>  $ Years        : int  2015 2016 2017 2018

Created on 2022-10-05 with reprex v2.0.2

  • Related