I have a dataset like this one :
df <- data.frame(Species = c("Sp A", "Other sp", "Other sp", "Other sp",
"Sp A", "Other sp", "Other sp"),
Study = c("A", "A", "A", "A",
"B", "B", "B"),
Value = c(1, 3, 4, 5, 3, 6, 7))
Looks like this :
> df
Species Study Value
1 Sp A A 1
2 Other sp A 3
3 Other sp A 4
4 Other sp A 5
5 Sp A B 3
6 Other sp B 6
7 Other sp B 7
I would like to compare the values of the species A to the values of the other species from a same study.
This is the plot I have now :
ggplot(df, aes(y = Value, x = Species)) +
geom_point(shape = 1) +
geom_line(aes(group = Study), color = "gray50") +
theme_bw()

I don't want the vertical lines. Instead of this, I would like to have 5 lines, 3 starting from the lower "Sp A" point toward the 3 corresponding "Other sp" points from the same study (A) and 2 starting from the upper "Sp A" toward the 2 other points from the same study (B).
There may be a more elegant way to do it, but here's a solution that works. The trick is to rearrange the data slightly and then use geom_segment:
library(tidyverse)
df <- data.frame(Species = c("Sp A", "Other sp", "Other sp", "Other sp",
"Sp A", "Other sp", "Other sp"),
Study = c("A", "A", "A", "A",
"B", "B", "B"),
Value = c(1, 3, 4, 5, 3, 6, 7))
# Split data
other <- df %>% filter(Species == "Other sp")
sp_a <- df %>% filter(Species == "Sp A")
# Recombine into the data set for plotting
df <- other %>%
inner_join(sp_a, by = "Study")
# Make the plot
ggplot(df, aes(x = Species.y, y = Value.y)) +
geom_segment(aes(xend = Species.x, yend = Value.x, colour = Study))

Adjust the plot as desired!
You can do this with geom_line if, for each level of Study, you duplicate the number of Sp A rows to match the number of Other sp rows and then assign a unique ID to each pair of Sp A and Other Sp for the group aesthetic.
library(tidyverse)
df %>% group_by(Study) %>%
slice(c(rep(1,length(Species[Species=="Other sp"])),2:n())) %>%
group_by(Study, Species) %>%
mutate(ID = paste0(Study, 1:n())) %>%
ggplot(aes(y = Value, x=Species, group=ID, colour=Study)) +
geom_point(shape=1) +
geom_line() +
theme_bw()

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With