Animated bar chart using ggplot and gganiminate - r

I have a bar plot created with ggplot which I would like to animate; the basic plot is ...
I have researched this on the web and created this code:-
Here is some Reprex data ...
Data <- as.data.frame(rbind(c("11 Mar'", "Male", "20-30"),
c("11 Mar'", "Male", "20-30"),
c("11 Mar'", "Female", "20-30"),
c("12 Mar'", "Female", "50-60"),
c("12 Mar'", "Female", "10-20"),
c("12 Mar'", "Male", "60-70"),
c("13 Mar'", "Female", "20-30"),
c("13 Mar'", "Female", "60-70"),
c("13 Mar'", "Male", "60-70"),
c("13 Mar'", "Male", "60-70"),
c("13 Mar'", "Female", "20-30"),
c("14 Mar'", "Female", "70-80"),
c("14 Mar'", "Female", "70-80"),
c("14 Mar'", "Male", "40-50")))
colnames(Data) <- c("Date", "Sex", "AgeGroup")
And this is my call to ggplot ...
ggplot(Data, aes(x = AgeGroup, fill = Sex, frame = Date, Cumulative = TRUE)) +
geom_bar(position = position_dodge2(preserve = "single")) +
scale_fill_manual(values = c("lightblue", "darkblue")) +
xlab("\nAge Group") + ylab("\nIndividuals") +
ggtitle("\nMarch - April 2020") +
scale_y_discrete(limits= c(2,4,6,8)) + theme_pc() +
transition_states(Date, transition_length = 4, state_length = 1) +
labs(title = 'Date: {closest_state}',
subtitle = "Age and Gender distribution",
caption = "data as of 0945 10 Apr 2020")
Unfortunately I am not getting the the desired output - the data is not being shown cumulatively
instead each frame of the plot refreshes to show only a single days result. I expected that geom_bar
would always accumulate the data across days but it doesn't seem to - I even have "Cumulative = TRUE"
in the ggplot call but still the result looks like this ...
Can anyone point me in the right direction ??

I have managed to get it.
I have reproduced the data set by duplicating the previous date's rows and adding to current date and so. So that the frequencies will be cumulative. I couldn't get it done in R. However, the data will be looking like this:
Data <- structure(list(Date = c("11 Mar'", "11 Mar'", "11 Mar'", "12 Mar'",
"12 Mar'", "12 Mar'", "12 Mar'", "12 Mar'", "12 Mar'", "13 Mar'",
"13 Mar'", "13 Mar'", "13 Mar'", "13 Mar'", "13 Mar'", "13 Mar'",
"13 Mar'", "13 Mar'", "13 Mar'", "13 Mar'", "14 Mar'", "14 Mar'",
"14 Mar'", "14 Mar'", "14 Mar'", "14 Mar'", "14 Mar'", "14 Mar'",
"14 Mar'", "14 Mar'", "14 Mar'", "14 Mar'", "14 Mar'", "14 Mar'"
), Sex = c("Female", "Male", "Male", "Female", "Female", "Female",
"Male", "Male", "Female", "Female", "Female", "Female", "Female",
"Female", "Female", "Male", "Male", "Male", "Male", "Male", "Female",
"Female", "Female", "Female", "Female", "Female", "Female", "Female",
"Male", "Male", "Female", "Male", "Male", "Male"), AgeGroup = c("20-30",
"20-30", "20-30", "10-20", "20-30", "50-60", "20-30", "20-30",
"60-70", "10-20", "20-30", "20-30", "20-30", "50-60", "60-70",
"20-30", "20-30", "60-70", "60-70", "60-70", "10-20", "20-30",
"20-30", "20-30", "50-60", "60-70", "70-80", "70-80", "20-30",
"20-30", "40-50", "60-70", "60-70", "60-70")), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -34L), spec = structure(list(
cols = list(Date = structure(list(), class = c("collector_character",
"collector")), Sex = structure(list(), class = c("collector_character",
"collector")), AgeGroup = structure(list(), class = c("collector_character",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
Then, enter_grow() and exit_fade() with alpha value needs to be added. Ensure that the bars are appearing in the same order of the category. In general, the bar for the the value is available at first is getting plotted irrespective of the color. The makes the shifting of the bar color while transiting.
ggplot(Data, aes(x = AgeGroup, fill = Sex, frame = Date)) +
geom_bar(position = position_dodge(preserve = "single")) +
scale_fill_manual(values = c("lightblue", "darkblue"), drop = TRUE) +
xlab("\nAge Group") + ylab("\nIndividuals") +
ggtitle("\nMarch - April 2020") +
scale_y_discrete(limits= c(2,4,6,8)) +
transition_states(Date, transition_length = 4, state_length = 1) + shadow_mark() +
enter_grow() +
exit_fade(alpha = 1)+
labs(title = 'Date: {closest_state}',
subtitle = "Age and Gender distribution",
caption = "data as of 0945 10 Apr 2020")

Related

circlize::circos.heatmap Add gaps between cells

I am creating a circular heatmap as follows:
suppressPackageStartupMessages({
library(circlize)
})
# input data
dput(annot)
structure(list(Specimen_Type = c("Both", "Plasma", "Both", "Both",
"Plasma", "Plasma", "Plasma", "Both", "Both", "Both", "Plasma",
"Plasma", "Both", "Both", "Both", "Both", "Both", "Both", "Both",
"Both", "Both", "Plasma", "Both", "Both", "Plasma", "Both", "Plasma",
"Plasma", "Both", "Plasma", "Both", "CSF", "Both", "Plasma",
"Both", "Both", "Both", "Plasma", "Both", "Plasma", "Both", "Plasma",
"Plasma", "Both", "Both", "Plasma", "Both", "Both", "Plasma",
"Plasma", "Plasma", "Plasma", "Plasma", "Both", "Both"), Sex = c("Female",
"Female", "Female", "Male", "Female", "Female", "Female", "Female",
"Female", "Female", "Male", "Male", "Male", "Male", "Male", "Male",
"Female", "Female", "Male", "Male", "Female", "Female", "Male",
"Male", "Female", "Male", "Male", "Male", "Female", "Female",
"Male", "Male", "Female", "Female", "Male", "Male", "Female",
"Male", "Male", "Male", "Male", "Female", "Male", "Male", "Female",
"Female", "Male", "Male", "Female", "Male", "Male", "Male", "Female",
"Female", "Female")), row.names = c("15635-29", "15635-31", "15635-32",
"15635-37", "15635-38", "15635-182", "15635-42", "15635-43",
"15635-45", "15635-46", "15635-53", "15635-215", "15635-58",
"15635-60", "15635-63", "15635-68", "15635-70", "15635-75", "15635-80",
"15635-81", "15635-87", "15635-90", "15635-100", "15635-101",
"15635-108", "15635-120", "15635-127", "15635-129", "15635-132",
"15635-134", "15635-135", "15635-1", "15635-2", "15635-251",
"15635-7", "15635-11", "15635-145", "15635-148", "15635-150",
"15635-154", "15635-156", "15635-158", "15635-161", "15635-169",
"15635-170", "15635-187", "15635-197", "15635-214", "15635-228",
"15635-225", "15635-246", "15635-254", "15635-234", "15635-239",
"15635-279"), class = "data.frame")
split <- factor(annot$Specimen_Type)
col_fun1 <- list("Male" = "navy",
"Female" = "deeppink4",
'Plasma' = '#fcff5c',
'CSF' = '#8d14ff',
'Both' = '#14f9ff')
circos.par(start.degree = 30, gap.degree = 1, points.overflow.warning = FALSE)
circos.heatmap(annot,
split = split,
col = unlist(col_fun1),
track.height = 0.4,
bg.border = "gray50", bg.lty = 1.5,
show.sector.labels = T)
circos.clear()
How do I add gaps between individual cells in the heatmap?
I needed to update the circlize package and add cell.border = "white" param.

A graph with two values as points and mean value with other shape

 Problem:
I can't find the right way to make a plot with values from a given variable with points and plot the value of the mean with another different shape. So far I find a way of doing this, but mean value appears in the color legend also which is something I don't want to. How could I get the desired output? Should I use stat_summary?
NOTE: Variables must be ordered by the mean value among groups by multimorbidity (if it is something important for the solution proposed) this is why I am using reorder_within and scale_x_reordered.
source("https://raw.githubusercontent.com/dgrtwo/drlib/master/R/reorder_within.R")
library(tidyverse)
foo %>%
group_by(multimorbidity, variables) %>%
mutate(Mean = mean(varimportance),
aux_mean = Mean) %>%
ungroup() %>%
spread(Gender, varimportance) %>%
gather(Gender, varimportance, -multimorbidity, -variables, -aux_mean) %>%
mutate(type = if_else(Gender %in% c("Male", "Female"), "Gender", "Mean")) %>%
ggplot(aes(reorder_within(variables, aux_mean, multimorbidity), varimportance,
color = Gender, shape = type)) +
geom_point() +
scale_x_reordered() +
scale_shape_manual(values = c(21, 24)) +
coord_flip() +
facet_wrap(multimorbidity~., scales = "free")
Created on 2019-03-20 by the reprex package (v0.2.1)
The desired output:
dput for foo:
foo <- structure(list(
Gender = c(
"Male", "Male", "Male", "Male", "Male",
"Female", "Female", "Female", "Female", "Female", "Female", "Female",
"Female", "Female", "Female", "Male", "Male", "Male", "Male",
"Male"
), multimorbidity = c(
"Yes", "Yes", "Yes", "Yes", "Yes",
"No", "No", "No", "No", "No", "Yes", "Yes", "Yes", "Yes", "Yes",
"No", "No", "No", "No", "No"
), variables = c(
"bmi", "income",
"soccap", "alternattr", "occhaz", "bmi", "income", "soccap",
"alternattr", "occhaz", "bmi", "income", "soccap", "alternattr",
"occhaz", "bmi", "income", "soccap", "alternattr", "occhaz"
),
varimportance = c(
73.1234145437324, 51.0029811829917, 100,
0, 90.9926659603591, 81.1949541852942, 48.2402164701156,
100, 0, 9.10509052698692, 66.7759248406279, 31.69991730502,
100, 4.7914221037359, 93.4636133674693, 70.8853809607131,
75.004433319282, 100, 0, 43.7326141975936
)
), class = c(
"tbl_df",
"tbl", "data.frame"
), row.names = c(NA, -20L))

X- axis labels are not properly aligned in R barplot

I have data.table data to create a stacked chart and with grouping using below code:
causesDf <- causesDf[, c('Type', 'Gender', 'Total')]
causesSort <- causesDf[, lapply(.SD, sum),
by=list(causesDf$Type, causesDf$Gender)]
and Data will be like below:
causesDf causesDf.1 Total
1: Illness (Aids/STD) Female 2892
2: Change in Economic Status Female 4235
3: Cancellation/Non-Settlement of Marriage Female 6126
4: Family Problems Female 133181
5: Illness (Aids/STD) Male 5831
6: Change in Economic Status Male 31175
7: Cancellation/Non-Settlement of Marriage Male 5170
and so on..
I am trying to make barplot like below:
barpos <- barplot(sort(causesSort$Total, decreasing=TRUE),
col=c("red","green"), xlab="", ylab="",
horiz=FALSE, las=2)
legend("topright", c("Male","Female"), fill=c("red","green"))
end_point <- 0.2 + nrow(causesSort) + nrow(causesSort) - 0.1
text(seq(0.1, end_point, by=1), par("usr")[3] - 30,
srt=60, adj= 1, xpd=TRUE,
labels=paste(causesSort$causesDf), cex=0.65)
but X-labels are not aligning properly, did I miss anything?
Expected output like:
Edited:
causesSort
structure(list(causesDf = c("Illness (Aids/STD)", "Change in Economic Status",
"Cancellation/Non-Settlement of Marriage", "Physical Abuse (Rape/Incest Etc.)",
"Dowry Dispute", "Family Problems", "Ideological Causes/Hero Worshipping",
"Other Prolonged Illness", "Property Dispute", "Fall in Social Reputation",
"Illegitimate Pregnancy", "Failure in Examination", "Insanity/Mental Illness",
"Love Affairs", "Professional/Career Problem", "Divorce", "Drug Abuse/Addiction",
"Not having Children(Barrenness/Impotency", "Causes Not known",
"Unemployment", "Poverty", "Death of Dear Person", "Cancer",
"Suspected/Illicit Relation", "Paralysis", "Property Dispute",
"Unemployment", "Poverty", "Family Problems", "Illness (Aids/STD)",
"Drug Abuse/Addiction", "Other Prolonged Illness", "Death of Dear Person",
"Causes Not known", "Cancer", "Not having Children(Barrenness/Impotency",
"Cancellation/Non-Settlement of Marriage", "Paralysis", "Physical Abuse (Rape/Incest Etc.)",
"Professional/Career Problem", "Love Affairs", "Fall in Social Reputation",
"Dowry Dispute", "Ideological Causes/Hero Worshipping", "Illegitimate Pregnancy",
"Failure in Examination", "Change in Economic Status", "Insanity/Mental Illness",
"Divorce", "Suspected/Illicit Relation", "Not having Children (Barrenness/Impotency",
"Not having Children (Barrenness/Impotency"), causesDf.1 = c("Female",
"Female", "Female", "Female", "Female", "Female", "Female", "Female",
"Female", "Female", "Female", "Female", "Female", "Female", "Female",
"Female", "Female", "Female", "Female", "Female", "Female", "Female",
"Female", "Female", "Female", "Male", "Male", "Male", "Male",
"Male", "Male", "Male", "Male", "Male", "Male", "Male", "Male",
"Male", "Male", "Male", "Male", "Male", "Male", "Male", "Male",
"Male", "Male", "Male", "Male", "Male", "Female", "Male"), Total = c(2892,
4235, 6126, 2662, 31206, 133181, 776, 69072, 4601, 4697, 2391,
12054, 33352, 21339, 1596, 2535, 1205, 5523, 148134, 3748, 7905,
4707, 2878, 8093, 2284, 14051, 23617, 24779, 208771, 5831, 28841,
125493, 5614, 304985, 6180, 2299, 5170, 5002, 1330, 10958, 23700,
8767, 764, 1342, 103, 14951, 31175, 60877, 1598, 6818, 544, 222
)), row.names = c(NA, -52L), class = c("data.table", "data.frame"
)
# , .internal.selfref = <pointer: 0x00000000098d1ef0> # seems not to work
)
If you don't rely on 45° rotation (that one is a bit more tricky) you could use this solution.
First we need to reshape the data by sex.
library(reshape2)
df2 <- dcast(causesSort, ... ~ causesDf.1 , value.var="Total")
Then we generate rownames from the type column and delete this column.
rownames(df2) <- df2[, 1]
df2 <- df2[, -1]
Then we order the data by one column, e.g. by Female.
df2 <- df2[order(-df2$Female), ]
The labels are the rownames.
# labs <- rownames(df2)
However, since they are very long (and bad for the reader's eye!), we may have to think of shorter ones. A workaround is to shorten them a little.
labs <- substr(sapply(strsplit(rownames(df2), " "),
function(x) x[1]), 1, 8)
Now we are able to apply barplot().
pos <- barplot(t(df2), beside=TRUE, xaxt="n",
col=c("#3C6688", "#45A778"), border="white")
pos gives us a matrix of bar positions, because we have a grouped plot we need the column means. We can use it to plot the axis.
axis(1, colMeans(pos), labs, las=2)
Result
Here is ggplot2 solution. This may provide better control over the final output
library(dplyr)
library(ggplot2)
#Rename columns names
names(causesDf) <- c('Type', 'Gender', 'Total')
#sort male before females
causesDf$Gender<-factor(causesDf$Gender, levels=c("Male", "Female"), ordered=TRUE)
#sort types by total sum and sort in decreasing order
sorted<-causesDf %>% group_by(Type) %>% summarize(gtotal=sum(Total)) %>% arrange(desc(gtotal))
causesDf$Type<-factor(causesDf$Type, levels=sorted$Type, ordered=TRUE)
#plot graph
g<-ggplot(causesDf, aes(x=Type, y=Total, group=Gender, fill=Gender)) +
geom_col(position = "dodge") +
theme(axis.text.x = element_text(angle = 45, hjust=1)) +
scale_fill_manual(values = alpha(c("blue", "green"), .5))
print(g)

Best way to analyze correlation between 3 different categorical variables

I'm trying to run some analysis and running into a roadblock (more like a mental block)...
Goal
I have 3 different factor variables:
Cohort: Analyst, Associate, Manager, Sr. Manger, Director, ED, VP
Gender: Male, Female
Timeframe: Mid-Year, Year-End, Beyond
I want to check to see if there is any difference in Gender across Cohort and Timeframe. I.e., are female analysts more likely to fall into Timeframe = "Beyond" than their Male counterparts.
Code
My initial thought is to do something like this:
library(dplyr)
x <- df %>%
filter(Gender %in% c("Male","Female")) %>%
filter(!is.na("Timeframe")) %>%
group_by(Timeframe, Cohort, Gender) %>%
summarise(n = n()) %>%
mutate(freq = 100 * (n / sum(n)))
But this is giving me percents that don't quite make sense. Ideally I'd like to conclude: "In the Analyst cohort, there is or is not a big difference in the timeframe Year-end or Mid-year or Beyond for gender"
Data
dput(head(df1,30))
structure(list(V1 = c("Female", "Male", "Male", "Male", "Male",
"Female", "Male", "Female", "Male", "Female", "Male", "Female",
"Male", "Female", "Female", "Female", "Male", "Female", "Female",
"Male", "Female", "Female", "Male", "Male", "Female", "Female",
"Male", "Male", "Female", "Female"), V2 = c("Executive Director",
"Executive", "Vice President", "Manager", "Director", "Executive Director",
"Manager", "Senior Manager", "Senior Manager", "Vice President",
"Director", "Senior Manager", "Manager", "Senior Manager", "Senior Manager",
"Senior Manager", "Executive Director", "Senior Manager", "Manager",
"Director", "Senior Manager", "Associate", "Vice President",
"Senior Manager", "Executive Director", "Manager", "Executive Director",
"Director", "Associate", "Senior Manager"), V3 = c("Beyond",
"Beyond", "Beyond", "Beyond", "Beyond", "Mid-Year Promotion",
"Beyond", "Year End Promotion", "Beyond", "Year End Promotion",
"Beyond", "Beyond", "Beyond", "Beyond", "Beyond", "Year End Promotion",
"Beyond", "Beyond", "Beyond", "Beyond", "Beyond", "Year End Promotion",
"Beyond", "Beyond", "Beyond", "Year End Promotion", "Beyond",
"Beyond", "Beyond", "Beyond")), row.names = c("1", "2", "4",
"5", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16",
"17", "19", "21", "22", "23", "24", "25", "27", "28", "29", "30",
"31", "32", "33", "34", "35"), class = "data.frame")
I'm really a fan of 1 picture == 1000 words, so here are two methods to see what is possible in R visually.
1. Advanced method
This method uses cumulated percentages and cumulated sums with the gganimate and ggplot2 packages. You can play with the parameters (e.g., nframes) to tweak it to your liking.
Code
g <- ggplot(dfcount, aes(x = gender, y = c, fill = timeframe)) +
geom_col(position = "identity") +
labs(title = "Gender and Promotion at Goliath National Bank",
subtitle = "Career level: {closest_state}",
x = "Gender",
y = "Number of employees",
fill = "Time of promotion") +
geom_label(aes(y = c, label = text)) +
scale_fill_manual(values = c("#ABE188", "#F7EF99", "#F1BB87"),
guide = guide_legend(reverse = TRUE)) +
transition_states(cohort, transition_length = 1, state_length = 3)
animate(g, nframes = 300)
Data
set.seed(1701)
g <- c("Female", "Male")
c <- c("Analyst", "Associate", "Manager", "Senior Manager", "Director",
"Executive Director", "Vice President")
t <- c("Mid-Year", "Year-End", "Beyond")
df <- data.frame(
gender = factor(sample(g, 1000, c(0.39, 0.61),
replace = TRUE), levels = g),
cohort = factor(sample(c, 1000, c(0.29, 0.34, 0.14, 0.11, 0.07, 0.04, 0.01),
replace = TRUE), levels = c),
timeframe = factor(sample(t, 1000, c(0.05, 0.35, 0.6),
replace = TRUE), levels = t))
library(dplyr)
library(ggplot2)
library(gganimate)
dfcount <- df %>%
group_by(gender, cohort, timeframe) %>%
summarize(n = n()) %>%
mutate(cum = cumsum(n)) %>%
mutate(perc = n / sum(n)) %>%
mutate(cumperc = cumsum(perc)) %>%
mutate(text = paste(round(perc*100, 1), "%"))
dfcount <- dfcount[order(dfcount$cohort, dfcount$gender, desc(dfcount$c)), ]
so that
> head(dfcount)
# A tibble: 6 x 8
# Groups: gender, cohort [2]
gender cohort timeframe n c perc cperc text
<fct> <fct> <fct> <int> <int> <dbl> <dbl> <chr>
1 Female Analyst Beyond 73 126 0.579 1 57.9 %
2 Female Analyst Year-End 48 53 0.381 0.421 38.1 %
3 Female Analyst Mid-Year 5 5 0.0397 0.0397 4 %
4 Male Analyst Beyond 95 172 0.552 1 55.2 %
5 Male Analyst Year-End 70 77 0.407 0.448 40.7 %
6 Male Analyst Mid-Year 7 7 0.0407 0.0407 4.1 %
2. Simple approach
It can also be as simple as:
Code
plot(table(df$gender, df$timeframe),
main = "Gender vs. Timeframe",
sub = paste("A comparison of the careers of",
count(subset(df, gender == "Female")), "women and",
count(subset(df, gender == "Male")), "men"),
ylab = "Time of promotion")
Everything after the first line is optional. Obviously you can make this plot much prettier using ggplot2, waffle, or similar.
Data
set.seed(1701)
g <- c("Female", "Male")
c <- c("Analyst", "Associate", "Manager", "Senior Manager", "Director",
"Executive Director", "Vice President")
t <- c("Mid-Year", "Year-End", "Beyond")
df <- data.frame(
gender = factor(sample(g, 1000, c(0.39, 0.61),
replace = TRUE), levels = g),
cohort = factor(sample(c, 1000, c(0.29, 0.34, 0.14, 0.11, 0.07, 0.04, 0.01),
replace = TRUE), levels = c),
timeframe = factor(sample(t, 1000, c(0.05, 0.35, 0.6),
replace = TRUE), levels = t))
so that
> head(df)
gender cohort timeframe
1 Male Associate Year-End
2 Female Analyst Year-End
3 Male Manager Beyond
4 Male Associate Beyond
5 Female Associate Year-End
6 Male Manager Beyond
EJJ is right in his comment - you need to ungroup after the summarise function. Otherwise, you'll be computing group-wise percentages, rather than percentages of the whole.
x=df %>% filter(Gender %in% c('Male',"Female")) %>%
filter(!is.na(`Promotion Timeframe`)) %>%
group_by(`Promotion Timeframe`,Management_Level,Gender) %>%
dplyr::summarise(n=n()) %>%
ungroup() %>%
mutate(freq = 100* (n/sum(n)))
Maybe you can just inspect the frequency matrix like:
table(df1[df1$V1=="Male",2:3])
table(df1[df1$V1=="Female",2:3])
This gives you an first impression on how your data is distributed.
For further investigation you may specify your Null hypotheses a bit more precisely in order to setup the right test.
Have a look at at eg. the pearson Chi square test like:
cntTable <- table(df1[,c(1,3)])
chisq.test(cntTable)

4 variables , 3 of which have 2 groups with overlayed bar plots in RStudio - Male and Female admitted and not admitted

enter link description hereI am facing an issue. I want to plot all four variables in RStudio. Where I appear to have 2 groups for 3 variables and a Count. Yet do not have a clue how to do this with ggplot2. On xlim axes shall be age_band and sex. On y axis Count of those admitted and not admitted. I want the legend bellow the overlayed barplot. Can someone help? I've searched on stackoverflow and could not find a good reproducible code.
dput(head(ds_sum_age_sex, 16))
structure(list(age_band = c("0 yrs", "0 yrs", "0 yrs", "0 yrs",
"1-4 yrs", "1-4 yrs", "1-4 yrs", "1-4 yrs",
"10-14 yrs", "10-14 yrs", "10-14 yrs", "10-14 yrs",
"15-19 yrs", "15-19 yrs", "15-19 yrs","15-19 yrs"),
sex = c("Female", "Female", "Male", "Male", "Female",
"Female", "Male", "Male", "Female", "Female",
"Male", "Male", "Female", "Female", "Male", "Male"),
patient.class = c("Not Admitted", "ORDINARY ADMISSION",
"Not Admitted", "ORDINARY ADMISSION", "Not
Admitted", "ORDINARY ADMISSION", "Not
Admitted", "ORDINARY ADMISSION",
"Not Admitted", "ORDINARY ADMISSION", "Not
Admitted", "ORDINARY ADMISSION", "Not
Admitted", "ORDINARY ADMISSION",
"Not Admitted", "ORDINARY ADMISSION"),
Count = c(5681L, 1458L, 7667L, 2154L, 8040L, 2481L, 11737L,
3601L, 2904L, 938L, 3883L, 1233L, 3251L, 1266L,
2465L, 1031L)),
row.names = c(NA, -16L), class = c("tbl_df", "tbl",
"data.frame"
))
Here's my 30-second attempt:
library(ggplot2)
# reduce the whitespace ...
x$patient.class <- gsub("[[:space:]]+", " ", x$patient.class)
ggplot(x, aes(age_band, Count, shape=sex, color=patient.class)) +
geom_point(size=3)
I edited your dput() data manually and then tried this using facet_wrap,
library(dplyr)
library(ggplot2)
test_data %>%
group_by(age_band, sex, patient.class) %>%
summarise(total_count = sum(Count)) %>%
ggplot(data = ., aes(age_band, total_count)) +
geom_bar(aes(fill = patient.class), stat = "identity") +
facet_wrap(~ sex, nrow = 2, ncol = 1)

Resources