Home > Net >  Adding geom_line between data points with different geom_boxplot fill variable
Adding geom_line between data points with different geom_boxplot fill variable

Time:08-03

Hi I have a much larger data frame but a sample dummy df is as follows:

set.seed(23)
df = data.frame(name = c(rep("Bob",8),rep("Tom",8)),
                topic = c(rep(c("Reading","Writing"),8)),
                subject = c(rep(c("English","English","Spanish","Spanish"),4)),
                exam = c(rep("First",4),rep("Second",4),rep("First",4),rep("Second",4)),
                score = sample(1:100,16))

I have to plot it in the way shown in the picture below (for my original data frame) but with lines connecting the scores corresponding to each name between the first and second class in the exam variable, I tried geom_line(aes(group=name)) but the lines are not connected in the right way. Is there any way to connect the points that also respects the grouping by the fill variable similar to how the position_dodge() helps separate the points by their fill grouping? Thanks a lot!

library(ggplot2)
df %>% ggplot(aes(x=topic,y=score,fill=exam))  
    geom_boxplot(outlier.shape = NA)   
    geom_point(size=1.75,position = position_dodge(width = 0.75))  
    facet_grid(~subject,switch = "y")

enter image description here

CodePudding user response:

One option to achieve your desired result would be to group the lines by name and topic and do the dodging of lines manually instead of relying on position_dogde. To this end convert topic to a numeric for the geom_line and shift the position by the necessary amount to align the lines with the dodged points:

set.seed(23)
df <- data.frame(
  name = c(rep("Bob", 8), rep("Tom", 8)),
  topic = c(rep(c("Reading", "Writing"), 8)),
  subject = c(rep(c("English", "English", "Spanish", "Spanish"), 4)),
  exam = c(rep("First", 4), rep("Second", 4), rep("First", 4), rep("Second", 4)),
  score = sample(1:100, 16)
)

library(ggplot2)

ggplot(df, aes(x = topic, y = score, fill = exam))  
  geom_boxplot(outlier.shape = NA)  
  geom_point(size = 1.75, position = position_dodge(width = 0.75))  
  geom_line(aes(
    x = as.numeric(factor(topic))   .75 / 4 * ifelse(exam == "First", -1, 1),
    group = interaction(name, topic)
  ))  
  facet_grid(~subject, switch = "y")

  • Related