Here is my sample data
mydata = data.frame (student =c("A","A","A","A","A","A","A","A","A",
"A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","B","B",
"B","B","B","B","B","B"),
subject = c("His","His","His","His","His","His","His","His",
"Geo", "Geo","Geo","Geo","Geo","Geo","Geo","Geo","His","His","His","His","His","His",
"His","His","Geo","Geo","Geo","Geo","Geo","Geo","Geo", "Geo"),
year = c("2001","2001","2001","2001","2002","2002",
"2002","2002","2001","2001","2001","2001","2002","2002","2002","2002", "2001","2001","2001","2001","2002","2002","2002",
"2002", "2001","2001","2001","2001","2002","2002","2002","2002"), majortype=c("total", "total", "passed", 'passed',
"total", "total", "passed", 'passed',"total", "total", "passed", 'passed',
"total", "total", "passed", 'passed', "total", "total", "passed", 'passed',
"total", "total", "passed", 'passed',"total", "total", "passed", 'passed',
"total", "total", "passed", 'passed'),
type=c("low income", "high income", "low income", "high income",
"low income", "high income", "low income", "high income", "low income",
"high income", "low income", "high income", "low income", "high income",
"low income", "high income", "low income", "high income", "low income",
"high income", "low income", "high income", "low income", "high income",
"low income", "high income", "low income", "high income", "low income",
"high income", "low income", "high income"),
value = c(104,106,67,89,34, 67,12,56,97,56,67,45,123,134,100,111, 124,98,
100,90,78,90,65,80,123,78,100,98, 77,67,56,63))
I am trying to achieve a stacked (by majortype) and grouped (by year and type) and then facet wrapped by subject and student. So I have the following code:
ggplot(mydata, aes(fill=majortype, y=value, x=year))
geom_bar(position="dodge", stat="identity")
facet_wrap(student~subject)
xlab("") ylab("Number of students") labs(fill="")
theme_minimal()
theme(text = element_text(size=15),
plot.title = element_text(size=20, face="bold"),
axis.text = element_text(size=9))
It pretty much gives me what I want, but Im really struggling to put stacked bars of the number of low income and high income within each individual bar. Ideally I would love to have low income be a darker shade and then the number of high income within each group be a lighter shade of these colors here.
I tried the following code too, which gives me the stacked by type, but I cant seem to now group this by year AND majortype. For each year I would like two stacked bars, red for total students (stacked by low vs high income) and then green for passed students (stacked by low vs high income).
ggplot(mydata, aes(fill=type, y=value, x=year))
geom_bar(position="stack", stat="identity")
facet_wrap(student~subject)
xlab("") ylab("Number of students") labs(fill="")
theme_minimal()
theme(text = element_text(size=15),
plot.title = element_text(size=20, face="bold"),
axis.text = element_text(size=9))
Any help would be appreciated! If it helps at all, I am looking to create something like this:
CodePudding user response:
Updated following OP's comment about wanting dodged and stacked bars: dodged by majortype
; stacked by type
.
Combining dodged and stacked bars is not a feature of ggplot: https://github.com/tidyverse/ggplot2/issues/2267
However, with help from this link: ggplot2 - bar plot with both stack and dodge and a bit of additional tinkering you could try this...
library(ggplot2)
library(dplyr)
# prepare data so that values are in effect stacked and in the right order
dat <-
mydata %>%
group_by(year, subject, student, majortype) %>%
arrange(type) %>%
mutate(val_cum = cumsum(value))
ggplot(dat, aes(fill = majortype, y = val_cum, x = year))
geom_col(data = filter(dat, type == "low income"), position = position_dodge2(width = 0.9), alpha = 0.5)
geom_col(data = filter(dat, type == "high income"), position = position_dodge2(width = 0.9), alpha = 1)
geom_tile(aes(y = NA_integer_, alpha = type))
scale_fill_manual(breaks = c("passed", "total"),
labels = c("High income - passed", "High income - total"),
values = c("red", "blue"))
guides(alpha = guide_legend(override.aes = list(fill = c("red", "blue"), alpha = c(0.5, 0.5))))
scale_alpha_manual(breaks = c("high income", "low income"),
labels = c("Low income - passed", "Low income - total"),
values = c(1, 0.5))
facet_wrap(student~subject)
labs(x = NULL,
y = "Number of students",
fill = NULL,
alpha = NULL)
theme_minimal()
theme(text = element_text(size=15),
plot.title = element_text(size=20, face="bold"),
axis.text = element_text(size=9))
Created on 2022-05-09 by the reprex package (v2.0.1)