How to Get a Barplot with Several Variables Side by Side Grouped by a Factor

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

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")

Sample Image

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

output

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")

Sample Image

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')

Sample Image

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")

Sample Image

Or:

ggplot(df, aes(x = as.factor(indicator), y = percent, fill = as.factor(year))) +
geom_bar(stat = "identity", position = "dodge")

Sample Image

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)

Sample Image



Related Topics



Leave a reply



Submit