I am analysing some data with a binomial distribution. We have 2 possible choices for a stimulus, and patients (female and male) have to decide whether they feel pain (1) or not (0).
I would like to plot a bargraph showing the number of patients who choose 0 or 1, in a rotated way.
An idea of the graph I am looking for is the following, from Sevarika et al, 2022.
#my data
id<-c(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10)
trt<-c("C","E","C","E","C","E","C","E","C","E","C","E","C","E","C","E","C","E","E","C")
response<-c(0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1)
sex<-c(rep("male",5),rep("female",5))
data<-data.frame(id,trt,response,sex)
So my objective is a flipped boxplot where females and males are separated, and the number of 1 or 0 is shown on each side of the axis. I mean, where it says control, let it say 0, where it says treatment let it say 1, and the top bar should be males and the bottom bar should be females.
Thank you very much, best regards
CodePudding user response:
Base R way:
tab <- t(table(data$response, data$sex) * c(-1, 1))
tab <- tab / rowSums(abs(tab)) * 100
frame()
par(mar=c(2.5, 1, 2, 1))
lab.x <- seq(-100, 100, 25)
plot.window(range(lab.x), c(0, 1))
axis(1, at=lab.x, labels=abs(lab.x))
abline(v=0)
abline(v=c(-1, 1)*50, lty=2)
bar.mid <- c(.3, .7)
bar.ht <- .25
rect(c(tab), bar.mid - bar.ht/2, 0, bar.mid bar.ht/2,
col=rep(gray(c(.8, .2)), each=2))
mtext(c('No pain', 'Pain'), 3, at=c(-1, 1)*40, cex=1.3, line=.5)
text(min(lab.x), bar.mid, rownames(tab), adj=0)
CodePudding user response:
You probably need to wrangle your data into a more appropriate format for plotting. Here's one method of doing it:
library(tidyverse)
data %>%
count(response, sex) %>%
mutate(n = ifelse(response == 0, -n, n)) %>%
ggplot(aes(sex, n, fill = factor(response)))
geom_hline(yintercept = 0)
geom_hline(yintercept = c(-3, 3), linetype = 2, size = 0.2)
geom_col(position = 'identity', color = 'black', width = 0.5)
coord_flip()
scale_y_continuous(breaks = seq(-7, 7), name = 'count', limits = c(-7, 7))
scale_fill_manual(values = c("#bebebe", "#2a2a2a"), guide = 'none')
annotate('text', y = c(-4, 4), x = c(2.8, 2.8), vjust = 1, size = 6,
label = c('RESPONSE = 0', 'RESPONSE = 1'), fontface = 2)
scale_x_discrete(expand = c(0, 1), name = NULL)
theme_minimal(base_size = 16)
theme(axis.line.x = element_line(),
axis.ticks.x = element_line(),
panel.grid = element_blank())