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")
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")