Drawing a Barchart to Compare Two Sets of Data Using Ggplot2 Package

Drawing a barchart to compare two sets of data using ggplot2 package?

It is better to reshape your data into long format. You can do that with for example the melt function of the reshape2 package (alternatives are reshape from base R, melt from data.table (which is an extended implementation of the melt function of reshape2) and gather from tidyr).

Using your dataset:

# load needed libraries
library(reshape2)
library(ggplot2)

# reshape your data into long format
nyxlong <- melt(nyx, id=c("Number"))

# make the plot
ggplot(nyxlong) +
geom_bar(aes(x = Number, y = value, fill = variable),
stat="identity", position = "dodge", width = 0.7) +
scale_fill_manual("Result\n", values = c("red","blue"),
labels = c(" Yresult", " Xresult")) +
labs(x="\nNumber",y="Result\n") +
theme_bw(base_size = 14)

which gives the following barchart:

Sample Image

ggplot2 bar chart with two bars for each x value of data and two y-axis

Is that what you mean?

df=tribble(
~Id, ~Cat, ~Type, ~Value,
1, "A", "price", 13,
2, "A", "number", 5,
3, "B", "price", 19,
4, "B", "number", 12,
5, "C", "price", 8,
6, "C", "number", 11)

df %>% ggplot(aes(Cat))


df %>% ggplot(aes(x=Type, fill=Type, y=Value))+
geom_col()+
facet_grid(~Cat)

Sample Image

P.S.
I changed your values a bit because you could not see much when the differences were of the order of 10 ^ 7!

With these numbers, the logarithmic scale is better suited

df=tribble(
~Id, ~Cat, ~Type, ~Value,
1, "A", "price", 12745,
2, "A", "number", 5,
3, "B", "price", 34874368,
4, "B", "number", 143,
5, "C", "price", 84526,
6, "C", "number", 11)

df %>% ggplot(aes(x=Type, fill=Type, y=Value))+
geom_col()+
scale_y_continuous(trans='log10')+
facet_grid(~Cat)

Sample Image

Bar chart in R with 2 bars for each item

You need to reshape the data to draw a grouped bar chart.

Sample Image

library(reshape2)
library(ggplot2)

data.m <- melt(df, id.vars='dateyear')

ggplot(data.m, aes(dateyear, value)) +
geom_bar(aes(fill = variable), position = "dodge", stat="identity") + theme(axis.text.x = element_text(angle = 90, hjust = 1))

Grouped bar chart on R using ggplot2

To prepare data for grouped bar plot, use melt() function of reshape2 package

I. Loading required packages

    library(reshape2)
library(ggplot2)

II. Creating data frame df

    df <- data.frame(Person = c("Mr.A","Mr.B"), Cats = c(3,4), Dogs = c(1,2))
df
# Person Cats Dogs
# 1 Mr.A 3 1
# 2 Mr.B 4 2

III. Melting data using melt function

    data.m <- melt(df, id.vars='Person')
data.m
# Person variable value
# 1 Mr.A Cats 3
# 2 Mr.B Cats 4
# 3 Mr.A Dogs 1
# 4 Mr.B Dogs 2

IV. Grouped Bar plot by Person

   ggplot(data.m, aes(Person, value)) + geom_bar(aes(fill = variable), 
width = 0.4, position = position_dodge(width=0.5), stat="identity") +
theme(legend.position="top", legend.title =
element_blank(),axis.title.x=element_blank(),
axis.title.y=element_blank())

Legend on top, legend title removed, axis titles removed, adjusted bar widths and space between bars.

Sample Image

How to Create comparison bar graph

I have modified your code as below.

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

df2 <- df1 %>%
gather(Fig, Value, -Month) %>%
mutate(Month = factor(Month,
levels = c("Nov-16", "Dec-16", "Jan-17", "Feb-17", "Mar-17"))) %>%
arrange(Month)

bargraph <- ggplot(data = df2) +
geom_bar(aes(x = Month,
y = Value,
fill = Fig,
color = Fig),
stat = "identity",
position = position_dodge()) +
theme(legend.title=element_blank())
bargraph

Sample Image

To use ggplot2 to plot a group bar chart, we need to convert df1 from wide-format to long-format, as df2. And then, it is necessary to reorder the Month column because that determines the order on the x-axis. Therefore, I converted the Month column to factor and use arrange to reorder it.

In geom_bar, we need to specify stat = "identity" and position = position_dodge(). It is possible to use geom_col to create the same plot without stat = "identity".

To save the plot, we can use the ggsave function. You can specify the file directory in the filename argument.

ggsave(filename = "bargraph.jpg", plot = bargraph)

Finally, using mailr is really a completely different question. Please search for related questions on Stack Overflow. If you could not find the information you need, then you can consider to ask a new question.

DATA

df1 <- read.table(text = "Month    Fig1    Fig2
'Mar-17' 10 12
'Feb-17' 25 18
'Jan-17' 10 15
'Dec-16' 11 18
'Nov-16' 10 15",
header = TRUE, stringsAsFactors = FALSE)

ggplot bar chart with two dataframes


ggplot(mapping=aes(x=dat))+
geom_bar(data=y, aes(x=dat-0.1), fill="red", binwidth=0.1)+
geom_bar(data=x, fill="blue", binwidth=0.1)

The key here is that you are shifting the data by the same amount as one binwidth and that binwidth is less than the spacing between groups. The binning is done on the data after shifting, so that affects which bin the data appears in. Also, without setting the binwidth explicitly, how wide the bins are depend on the range of the plot (which is why it varies when xlim was varied and worked "nicely" for round values).

Sample Image

How to draw a grouped barplot of two dataframes?

What I got from your question is that you have one type of data for which you have individual cases, and one type of data for which you have proportions. These data should be represented on the same bar graph.

Since I don't have a sample of your data I'll use a standard dataset and reshape it a bit to reflect your case.

library(tidyverse)

# Suppose df1 is the equivalent of DepriSymptoms
df1 <- mpg[mpg$year == 1999,]

# And we'll shape df2 to be similar to DepriNorm (proportion data)
df2 <- mpg[mpg$year == 2008,]
df2 <- df2 %>% group_by(class) %>%
summarise(n = n()) %>%
ungroup() %>%
mutate(prop = n / sum(n))

head(df2)
#> # A tibble: 6 x 3
#> class n prop
#> <chr> <int> <dbl>
#> 1 2seater 3 0.0256
#> 2 compact 22 0.188
#> 3 midsize 21 0.179
#> 4 minivan 5 0.0427
#> 5 pickup 17 0.145
#> 6 subcompact 16 0.137

So in the data above we can count the cases in df1 but must use the prop column in df2. You can totally use the two layers approach, but you'd have to be mindful that layers can't see into other layers and thus the dodging from the bar groups is absent. Two tips here:

  • You can use geom_col() as a shortcut for geom_bar(..., stat = "identity"), so it will not try to count your proportion data.
  • You can use position = position_nudge(x = ...) to offset your bars so that they appear grouped, even though they are on different layers. You'd also have to change the width of the bars.
ggplot(df1, aes(class)) +
geom_bar(aes(y = after_stat(prop), group = 1, fill = "A"),
width = 0.4, position = position_nudge(0.22)) +
geom_col(aes(y = prop, fill = "B"), data = df2,
width = 0.4, position = position_nudge(-0.22))

Sample Image

Created on 2020-05-30 by the reprex package (v0.3.0)

ggplot grouped bar chart

First you have to arrange the data in the proper format for plotting:

library(reshape2)
df1 <- melt(df, id = "Year")

Or you could use the tidyr package:

library(tidyr)
df1 <- gather(df, variable, value, -Year)

Which may be easier to understand if you are not familiar with melt()

Basically, it says: "Gather all the variables in df except Year, calling the new key column variable and the new value column value"

library(ggplot2)
ggplot(df1, aes(Year, value)) +
geom_bar(aes(fill = variable), position = "dodge", stat = "identity")

Sample Image

If you prefer to format numbers with commas separating thousands:

library(ggplot2)
library(scales)
ggplot(df1, aes(Year, value)) +
geom_bar(aes(fill = variable), position = "dodge", stat = "identity") +
scale_y_continuous(name = "Values", labels = comma)

Sample Image

Barplot with 2 variables side by side

You have to reshape your data frame from wide to long and then you don't need to set bars for each condition separately.

Assuming that data frame is named df.

library(reshape2)
df.long<-melt(df)
ggplot(df.long,aes(Block,value,fill=variable))+
geom_bar(stat="identity",position="dodge")

Sample Image



Related Topics



Leave a reply



Submit