Given the following data, I compose a data frame with a factor and a numeric column.
X2 <- c(4,4,3,5,4,4,2,3,4,3,5,5,4,3,3,4,2,3,3,4,3,5,3,3,4,4,3,3,5,4,5,4,4,3,5,5,3,5,4,5,5,4,4,2,3,3,3,4,4,4,2,4,4,4,4,4,2,4,4,3,3,3,5,3,4,3,3,4,4,4,4,1,3,3,4,3,3,2,4,1)
X3 <- rep("I",40)
X4 <- rep("C",40)
Group <- c(X3,X4)
dat2 <- data.frame(X2,Group)
dat2$Group <- factor(dat2$Group)
levels(dat2$Group) = c("I","C")
Group <- c("C","I")
grp.mean <- c(3.8,3.375)
mu2 <- data.frame(Group,grp.mean)
I want to compose the following bar plot with vertical lines at the mean and here's, my code:
p2 <-ggplot(dat2, aes(x=X2))
geom_bar(aes(color=Group,fill=Group),alpha=0.4, position= position_dodge(preserve = "single"))
geom_vline(data=mu2, aes(xintercept=grp.mean, color=Group), linetype="dashed")
xlab("Density in Responses")
ylab("Levels")
theme_gray()
theme_grey(base_size = 30)
theme(axis.text=element_text(size=22),
axis.title=element_text(size=20,face="bold"),
legend.title=element_text(size=16),
legend.text=element_text(size=14))
theme(plot.title = element_text(hjust = 0.5,size=19,face="bold"))
p2
And I get a plot which checks all my expectations except one. When I have a value that one of the conditions (C and I) is blank, it automatically changes the place, and I don't know why! From my logic, it should remain in the same position and draw the bar in the right position. I attach an image so you can see what is going on.
As you can see the blue bar has taken the place of the red bar at the absence of a red bar (because it has 0 value). Does anyone know why is this happening and, is there any way I can fix this?
Thanks!
CodePudding user response:
One work-around is to count the number of observations before ggplot
, and plot the count information.
Note I have swapped X3
and X4
in your first Group
vector so that red is on the left and blue is on the right.
library(tidyverse)
X2 <- c(4,4,3,5,4,4,2,3,4,3,5,5,4,3,3,4,2,3,3,4,3,5,3,3,4,4,3,3,5,4,5,4,4,3,5,5,3,5,4,5,5,4,4,2,3,3,3,4,4,4,2,4,4,4,4,4,2,4,4,3,3,3,5,3,4,3,3,4,4,4,4,1,3,3,4,3,3,2,4,1)
X3 <- rep("I",40)
X4 <- rep("C",40)
Group <- c(X4,X3)
dat2 <- data.frame(X2,Group)
dat2$Group <- factor(dat2$Group)
levels(dat2$Group) = c("I","C")
Group <- c("C","I")
grp.mean <- c(3.8,3.375)
mu2 <- data.frame(Group,grp.mean)
dat2 %>% group_by(X2, Group) %>% summarize(n = n()) %>% complete(Group, fill = list(n = 0)) %>%
ggplot(aes(x=X2, n))
geom_bar(aes(color=Group,fill=Group),alpha=0.4, position= position_dodge(), stat = "identity")
geom_vline(data=mu2, aes(xintercept=grp.mean, color=Group), linetype="dashed")
xlab("Density in Responses")
ylab("Levels")
theme_gray()
theme_grey(base_size = 30)
theme(axis.text=element_text(size=22),
axis.title=element_text(size=20,face="bold"),
legend.title=element_text(size=16),
legend.text=element_text(size=14))
theme(plot.title = element_text(hjust = 0.5,size=19,face="bold"))
#> `summarise()` has grouped output by 'X2'. You can override using the `.groups`
#> argument.
Created on 2022-05-13 by the reprex package (v2.0.1)
CodePudding user response:
Like the others commenters i also got the opposite bar color so i changed the I/C values and it matched yours. I am not sure if my result would satisfy you, as i managed to make the blue bar to fill the whole space of X=1
Anyway, I also used a cleaner code to generate the table:
X2 <- c(4,4,3,5,4,4,2,3,4,3,5,5,4,3,3,4,2,3,3,4,3,5,3,3,4,4,3,3,5,4,5,4,4,3,5,5,3,5,4,5, #40
5,4,4,2,3,3,3,4,4,4,2,4,4,4,4,4,2,4,4,3,3,3,5,3,4,3,3,4,4,4,4,1,3,3,4,3,3,2,4,1)
# First col is the unique X2 values.
# Second col is Group, which is a factor. It is a repetition of I/C, each 40 times (40*I and then 40*C)
# grp.mean is a grouped mean (by each Group[I/C]) of X2.
dat2 <- data.frame(
X2,
Group=factor(rep(c("C","I"),each=40))
) %>% group_by(Group) %>% mutate(grp.mean=mean(X2)) %>% ungroup()
dat2 %>% ggplot(aes(X2,fill=Group))
geom_bar(position="dodge")
geom_vline(xintercept = dat2$grp.mean)