0

I'm trying to pair "Observed" and "Expected" bars for plastic counts at each site but can't figure out how to include my "Expected" columns in my geom_col plot. My report is due on the 30th (yikes!)

I'd like something akin to this (see below) but not using Excel (I've spent 2 days in R trying to crack it and am determined to succeed!)

enter image description here

My data frame is as follows:

df <- data.frame(
  Site_name = c("Albermarle", "Cabo Douglas", "Punta Puntas", 
                "Floreana Black Beach", "Punta Cormoran", "Loberia"),       Plastic_pieces = c(44, 215, 29, 31, 42, 260),
  Expected = rep(c(103.5), times = 6))

My geom_col code so far is:

ggplot(df, aes(x=Site.Name, y=Plastic_pieces, fill = Site.Name ))+
  geom_col()+
  theme_classic()+
  labs(y="Number of macroplastic pieces", x="Site Name")+
  theme(axis.line.x = element_line(size = 0.3, colour = "black"),
        axis.line.y = element_line(size = 0.3, colour = "black"),
        axis.line = element_line(size=1, colour = "black"),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        text=element_text(size = 12),
        axis.text.x=element_text(colour="black", size = 8),
        axis.text.y=element_text(colour="black", size = 12),
        axis.text.x.bottom = element_blank(),
        axis.title.x = element_blank(),
        axis.ticks.x.bottom = element_blank())+
        scale_fill_discrete(name="Site Name")+
  geom_text(aes(label=Plastic_pieces), position=position_dodge(width=0.9), vjust=-0.25)

enter image description here

I saw some code online that looked like it could help but I got pretty much the same result as above except that the bars were in descending order:

df %>%
  group_by(Plastic_pieces, Expected) %>%
  summarise(n=sum(Plastic_pieces, na.rm = TRUE)) %>%
  arrange(desc(Plastic_pieces)) %>%
  ggplot(aes(x=df$Site.Name, y=Plastic_pieces, fill = df$Site.Name)) +
  geom_col(position='dodge')

enter image description here

If anyone can help I'd be very grateful!

Cheers!

Marco Sandri
  • 23,289
  • 7
  • 54
  • 58

2 Answers2

0

The solution to this type of question is many times to reshape the data from wide to long format. I will do this with packages dplyr and tidyr.

library(dplyr)
library(tidyr)
library(ggplot2)

df %>%
  pivot_longer(
    cols = -1,
    names_to = 'Group',
    values_to = 'Value'
  ) %>%
  ggplot(aes(Site_name, Value, fill = Group)) +
  geom_col(position = position_dodge()) +
  geom_text(aes(label = Value), position = position_dodge(width = 0.9), vjust = -0.25) +
  labs(y="Number of macroplastic pieces", x="Site Name") +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 60,hjust = 1))

enter image description here

Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
0

Here an easy and brief solution for this. All you need to do is use melt() to transform your data and call for position = position_dodge() in your geom_col() call.

See here the code I used to plot your example data.

df <- data.frame(
  Site_name = c("Albermarle", "Cabo Douglas", "Punta Puntas", 
                "Floreana Black Beach", "Punta Cormoran", "Loberia"),       Plastic_pieces = c(44, 215, 29, 31, 42, 260),
  Expected = rep(c(103.5), times = 6))

library(reshape2)
df_melt = melt(df, id.vars = "Site_name")

ggplot(df_melt, aes(x = Site_name, y = value, fill = variable)) + 
  geom_col(position = position_dodge())
ljwharbers
  • 393
  • 2
  • 8