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")
How to get a barplot with several variables side by side grouped by a factor
You can use aggregate to calculate the means:
means<-aggregate(df,by=list(df$gender),mean)
Group.1 tea coke beer water gender
1 1 87.70171 27.24834 24.27099 37.24007 1
2 2 24.73330 25.27344 25.64657 24.34669 2
Get rid of the Group.1 column
means<-means[,2:length(means)]
Then you have reformat the data to be in long format:
library(reshape2)
means.long<-melt(means,id.vars="gender")
gender variable value
1 1 tea 87.70171
2 2 tea 24.73330
3 1 coke 27.24834
4 2 coke 25.27344
5 1 beer 24.27099
6 2 beer 25.64657
7 1 water 37.24007
8 2 water 24.34669
Finally, you can use ggplot2 to create your plot:
library(ggplot2)
ggplot(means.long,aes(x=variable,y=value,fill=factor(gender)))+
geom_bar(stat="identity",position="dodge")+
scale_fill_discrete(name="Gender",
breaks=c(1, 2),
labels=c("Male", "Female"))+
xlab("Beverage")+ylab("Mean Percentage")
Set order of variables in grouped barplot
You just need unique
in your levels
df$variable <- factor(df$variable, levels = unique(df$variable))
df$cluster <- factor(df$cluster, levels = unique(df$cluster))
and you will get
Creating a side by side bar plot with 1 continuous variable and 2 factor variables (one for stacking and the other for grouping bars)
You can't have both position_dodge
and position_stack
on a bar graph, so you need to get creative. You can get the effect you are looking for by faceting on quarter instead of HFGroup
, and filling by HFGroup
. You then make QuantGroup
your x axis. This gives you a 2-column stacked bar for each quarter. You then just adjust the facets so that they don't look like facets by reducing their spacing to zero and bringing the strips to the bottom:
ggplot(df, aes(QuantGroup, Values, fill = HFGroup)) +
geom_col() +
facet_grid( ~ QuarterPeriod, switch = "x") +
xlab("Quant Group by Quarter") +
theme(panel.spacing = unit(0, "points"),
strip.background = element_blank(),
strip.placement = "outside")
ggplot bar plot side by side using two variables
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')
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')
Plot multiple variables by year in the same bar plot
One solution would be:
library(ggplot2)
library(tidyverse)
library(dplyr)
df = data.frame(year = c(2015, 2019),
wdi_lfpr = c(55.6, 58.2),
wdi_lfprf = c(34.9, 38.2),
wdi_lfprm = c(77.0, 78.4)) %>%
pivot_longer(cols = 2:4, names_to = "indicator", values_to = "percent")
ggplot(df, aes(x = as.factor(year), y = percent, fill = indicator)) +
geom_bar(stat = "identity", position = "dodge")
Or:
ggplot(df, aes(x = as.factor(indicator), y = percent, fill = as.factor(year))) +
geom_bar(stat = "identity", position = "dodge")
How to make a bar-chart by using two variables on x-axis and a grouped variable on y-axis?
After speaking to the OP I found his data source and came up with this solution. Apologies if it's a bit messy, I have only been using R for 6 months. For ease of reproducibility I have preselected the variables used from the original dataset.
data <- structure(list(wkhtot = c(40, 8, 50, 40, 40, 50, 39, 48, 45,
16, 45, 45, 52, 45, 50, 37, 50, 7, 37, 36), happy = c(7, 8, 10,
10, 7, 7, 7, 6, 8, 10, 8, 10, 9, 6, 9, 9, 8, 8, 9, 7), stflife = c(8,
8, 10, 10, 7, 7, 8, 6, 8, 10, 9, 10, 9, 5, 9, 9, 8, 8, 7, 7)), row.names = c(NA,
-20L), class = c("tbl_df", "tbl", "data.frame"))
Here are the packages required.
require(dplyr)
require(ggplot2)
require(tidyverse)
Here I have manipulated the data and commented my reasoning.
data <- data %>%
select(wkhtot, happy, stflife) %>% #Select the wanted variables
rename(Happy = happy) %>% #Rename for graphical sake
rename("Life Satisfied" = stflife) %>%
na.omit() %>% # remove NA values
group_by(WorkingHours = cut(wkhtot, c(-Inf, 27, 32,36,42,Inf))) %>% #Create the ranges
select(WorkingHours, Happy, "Life Satisfied") %>% #Select the variables again
pivot_longer(cols = c(`Happy`, `Life Satisfied`), names_to = "Criterion", values_to = "score") %>% # pivot the df longer for plotting
group_by(WorkingHours, Criterion)
data$Criterion <- as.factor(data$Criterion) #Make criterion a factor for graphical reasons
A bit more data prep
# Creating the percentage
data.plot <- data %>%
group_by(WorkingHours, Criterion) %>%
summarise_all(sum) %>% # get the sums for score by working hours and criterion
group_by(WorkingHours) %>%
mutate(tot = sum(score)) %>%
mutate(freq =round(score/tot *100, digits = 2)) # get percentage
Creating the plot.
# Plotting
ggplot(data.plot, aes(x = WorkingHours, y = freq, fill = Criterion)) +
geom_col(position = "dodge") +
geom_text(aes(label = freq),
position = position_dodge(width = 0.9),
vjust = 1) +
xlab("Working Hours") +
ylab("Percentage")
Please let me know if there is a more concise or easier way!!
B
DataSource: https://www.europeansocialsurvey.org/downloadwizard/?fbclid=IwAR2aVr3kuqOoy4mqa978yEM1sPEzOaghzCrLCHcsc5gmYkdAyYvGPJMdRp4
R Barplot multiple variables by another variable
Try:
barplot(t(propVars),beside=T)
Related Topics
Passing Several Arguments to Fun of Lapply (And Others *Apply)
Adding a Company Logo to Shinydashboard Header
Difference Between Rbind() and Bind_Rows() in R
Install.Packages Fails in Knitr Document: "Trying to Use Cran Without Setting a Mirror"
How to Color Sliderbar (Sliderinput)
Replace Duplicated Elements with Na, Instead of Removing Them
How to Separate Comma Separated Values in R in a New Row
What Is Difference Between Dataframe and List in R
Identifying Dependencies of R Functions and Scripts
How to Convert Data Frame to Spatial Coordinates
R Color Scatter Plot Points Based on Values
R: How to Run Some Code on Load of Package
Shift Values in Single Column of Dataframe Up
How to Complete Missing Factor Levels in Data Frame
How to Sort All Dataframes in a List of Dataframes on the Same Column
Inputting Na Where There Are Missing Values When Scraping with Rvest