Connect means with a crossbar in ggplot2

Viewed 117

I have a data frame that looks like this

presence = rep(c("yes","no"),each=3,2)
students = sample(seq(0,100,by=10), 12, replace = TRUE)
year = rep(c("2015","2016"),each=2,6)

data = data.frame(presence, students, year)

I plot my data like this

ggplot(data, aes(as.factor(presence), students, color=factor(year))) +
  geom_jitter(size=4, alpha=0.4, shape=16,position = position_jitterdodge()) +
  stat_summary(
    aes(color = year),
    fun=mean, 
    fun.min = function(x) mean(x) - sd(x), 
    fun.max = function(x) mean(x) + sd(x),
    geom = "pointrange",  size = 0.4,
    position = position_dodge(0.8)
  )  +
  stat_summary(fun = mean, geom="line")

enter image description here

What I am really struggling to do is to find a way to connect with a line the dots in reds (mean values) and the dots in blue.

Is there any other way to do it except of geom_segment and make my plot look like this?

enter image description here

3 Answers

I suppose you do another stat_summary() with geom="line" and group = year, though I think it's a bit hard to read off the graph:

set.seed(12345)

presence = rep(c("yes","no"),each=3,2)
students = sample(seq(0,100,by=10), 12, replace = TRUE)
year = rep(c("2015","2016"),each=2,6)

data = data.frame(presence, students, year)

g = ggplot(data, aes(as.factor(presence), students, color=factor(year))) +
  geom_jitter(size=4, alpha=0.4, shape=16,position = position_jitterdodge()) +
  stat_summary(
    aes(color = year),
    fun=mean, 
    fun.min = function(x) mean(x) - sd(x), 
    fun.max = function(x) mean(x) + sd(x),
    geom = "pointrange",  size = 0.4,
    position = position_dodge(0.8)
  )  +
  stat_summary(fun = mean, geom="line")

g + stat_summary(aes(group = year),geom="line",
position=position_dodge2(0.8),fun="mean")

enter image description here

You could use geom_line but it would require you to add the data yourself. However, I am not familiar with stat_summary as I prefer to have the control over the process myself.

  • So I edited your code, to see if I could replicate it, and offer you an alternative to geom_segment.


data %>% 
        ggplot(
                mapping = aes(as.factor(presence), students, color=factor(year))
        )  + geom_line(
                data = data %>% group_by(year, presence) %>% summarise(students = mean(students)),
                mapping = aes(x = as.factor(presence), y = students,group = as.factor(year))
        )  + geom_point(
                data = data %>% group_by(year, presence) %>% summarise(students = mean(students)),
                mapping = aes(x = as.factor(presence), y = students,group = as.factor(year))
        ) + geom_jitter(size=4, alpha=0.4, shape=16,position = position_jitterdodge()) + geom_errorbar(
                data = data %>% group_by(year, presence) %>% summarise( sd = sd(students), students = mean(students)),
                aes(
                        ymin = students - sd,
                        ymax = students + sd
                ),
                width = 0.05
        )

enter image description here

Here is my try:

Lessons learned: Never give up!

set.seed(12345)

presence = rep(c("yes","no"),each=3,2)
students = sample(seq(0,100,by=10), 12, replace = TRUE)
year = rep(c("2015","2016"),each=2,6)

data = data.frame(presence, students, year)

data1 <- data %>% 
    group_by(year, presence) %>% 
    mutate(mean = mean(students)) %>% 
    mutate(min = mean(students) - sd(students)) %>% 
    mutate(max = mean(students) + sd(students)) 


ggplot(data1, aes(as.factor(presence), students, color=factor(year))) +  
    geom_bar(alpha=0, stat = "identity", position = "dodge", color="white") +
    geom_linerange(aes(ymin = min, ymax = max), position = position_dodge(width = 0.8)) +
    #geom_point(aes(y = mean), position = position_dodge(width = 0.8)) + 
    stat_summary(fun = mean, geom="point", color= "red", position = position_dodge(width = 0.8), aes(group=factor(year))) +
    stat_summary(fun = mean, geom="line", position = position_dodge(width = 0.8), aes(group=factor(year))) +
    geom_jitter(size=4, alpha=0.4, shape=16,position = position_jitterdodge()) +
    theme_classic() 

enter image description here

Related