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:
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)
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)
Bar chart in R with 2 bars for each item
You need to reshape the data to draw a grouped bar chart.
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.
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
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).
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 forgeom_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))
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")
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)
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")
Related Topics
Removing One Tablegrob When Applied to a Box Plot with a Facet_Wrap
How to Use Data.Table Within Functions and Loops
Counting the Frequency of an Element in a Data Frame
Merge Panel Data to Get Balanced Panel Data
In R, How to Add a Max by Group
Scraping with Rvest - Complete with Nas When Tag Is Not Present
Create Counter of Consecutive Runs of a Certain Value
Adding New Column with Diff() Function When There Is One Less Row in R
Repeat Vector When Its Length Is Not a Multiple of Desired Total Length
How to Split a Data Frame into Multiple Dataframes with Each Two Columns as a New Dataframe
R Fuzzy String Match to Return Specific Column Based on Matched String
How to Extract Certain Columns from a List of Data Frames
Collapse Continuous Integer Runs to Strings of Ranges
How to Convert Time (Mm:Ss) to Decimal Form in R