18

I want to create a barplot using ggplot in R studio using two variables side by side. I tried following other people suggestions I found online, but I cant get it to work.

Here's the data I'm using:

x <- c(5,17,31,9,17,10,30,28,16,29,14,34)

y <- c(1,2,3,4,5,6,7,8,9,10,11,12)

day <- c(1,2,3,4,5,6,7,8,9,10,11,12)

So, what I'm trying to do is have days on the x-axis and side by side barplots of x and y (with x & y being colored) corresponding to the day number.

First thing i did was make a data frame :

df1 <- data.frame(x,y,day)

and then I tried:

ggplot(df1, aes(x = day, y = x,y)) + geom_bar(stat = "identity",color = x, width = 1, position="dodge")

But I just can't get it to work properly. Any suggestions as to how I'd achieve this?

Renats Stozkovs
  • 2,549
  • 10
  • 22
  • 26
Electrino
  • 2,636
  • 3
  • 18
  • 40
  • follow-up question: Did you want the color to be based on the day? or is the color based on whether they are in the "x" or "y" group? – TaylorV Mar 15 '17 at 21:23

2 Answers2

39

You have the right idea, I think the melt() function from the reshape2 package is what you're looking for.

library(ggplot2)
library(reshape2)

x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
day <- c(1,2,3,4,5,6,7,8,9,10,11,12)


df1 <- data.frame(x, y, day)
df2 <- melt(df1, id.vars='day')
head(df2)

ggplot(df2, aes(x=day, y=value, fill=variable)) +
    geom_bar(stat='identity', position='dodge')

enter image description here

EDIT I think the pivot_longer() function from the tidyverse tidyr package might now be the better way to handle these types of data manipulations. It gives quite a bit more control than melt() and there's also a pivot_wider() function as well to do the opposite.

library(ggplot2)
library(tidyr)

x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
day <- c(1,2,3,4,5,6,7,8,9,10,11,12)


df1 <- data.frame(x, y, day)
df2 <- tidyr::pivot_longer(df1, cols=c('x', 'y'), names_to='variable', 
values_to="value")
head(df2)

ggplot(df2, aes(x=day, y=value, fill=variable)) +
    geom_bar(stat='identity', position='dodge')
TaylorV
  • 846
  • 9
  • 13
5

Or you could use facet_wrap to produce two plots:

  library("ggplot2")
  library("reshape")
  x <- c(5,17,31,9,17,10,30,28,16,29,14,34)
  y <- c(1,2,3,4,5,6,7,8,9,10,11,12)
  day <- c(1,2,3,4,5,6,7,8,9,10,11,12)
  df1 <- data.frame(x,y,day)
  df2 <- reshape::melt(df1, id = c("day"))
  ggplot(data = df2, aes(x = day, y = value, fill = variable)) + geom_bar(stat = "identity")+ facet_wrap(~ variable) + scale_x_continuous(breaks=seq(1,12,2))

enter image description here If you want the bars with color according to the day use fill = day:

ggplot(data = df2, aes(x = day, y = value, fill = day)) + geom_bar(stat = "identity") + facet_wrap(~ variable) + scale_x_continuous(breaks=seq(1,12,2)) 

enter image description here

Edgar Santos
  • 3,426
  • 2
  • 17
  • 29