DaniCee
DaniCee

Reputation: 3217

R: geom_signif in a ggplot2 plot with facets; why can't I specify comparisons that do not include the first group?

I am trying to do something that I have done in the past successfully, but now I am not sure if I am missing something or something has changed in newer versions, but for the life of me I cannot make it work...

I just want to make a faceted ggplot2 plot like the one below, using geom_signif on top of it to actually include the percentage change from each value plotted, compared to all the rest.

To make things simple, however, I am just adding "foo" to the geom_signif brackets (no percentage change values yet).

So I have a data frame like this one:

mydata <- data.frame(Rep=rep(paste0('rep',1:5), 4),
                     Population=rep(paste0(LETTERS[1:4],'cells'), each=5),
                     Value=c(runif(15,1,5), runif(5,30,40)))

    Rep Population     Value
1  rep1     Acells  3.906863
2  rep2     Acells  2.391534
3  rep3     Acells  2.417360
4  rep4     Acells  4.956607
5  rep5     Acells  1.018905
6  rep1     Bcells  3.348250
7  rep2     Bcells  1.979448
8  rep3     Bcells  3.499493
9  rep4     Bcells  4.161168
10 rep5     Bcells  4.705278
11 rep1     Ccells  1.854068
12 rep2     Ccells  4.514578
13 rep3     Ccells  3.430654
14 rep4     Ccells  4.418377
15 rep5     Ccells  1.228447
16 rep1     Dcells 39.763432
17 rep2     Dcells 36.528565
18 rep3     Dcells 31.575392
19 rep4     Dcells 34.956205
20 rep5     Dcells 39.882848

I just try to make the plot the following way; note that I want to save the plot in P and access it afterwards to include my actual values, so let's try to keep it that way.

As you can see though, the problem I am encountering is I can only include comparisons that include rep1 for some reason... the moment I try to include the comparison rep3 vs rep4 for example, it becomes ignored! Why is this happening?

P <- ggplot2::ggplot(mydata, ggplot2::aes(x=Rep, y=Value, group=1)) +
  ggplot2::geom_line(color="black") +
  ggplot2::geom_point(color="red", shape=16, size=5) +
  
  ggplot2::facet_wrap(.~Population, scales="free", ncol=2) +
  ggplot2::theme_light() +
  ggsignif::geom_signif(comparisons=list(c("rep1","rep2"),c("rep1","rep3"),c("rep3","rep4")),
                        annotation="foo",
                        textsize=5,
                        size=1)
# build the plot (get a list of data frames out of it)
P2 <- ggplot2::ggplot_build(P)
# in list 3 we have access to each annotation
head(P2$data[[3]], 20)
# plot
grDevices::pdf.options(reset = TRUE, onefile = FALSE)
grDevices::pdf(file="test.pdf", height=10, width=10)
print(#or ggsave()
  graphics::plot(ggplot2::ggplot_gtable(P2))
)
grDevices::dev.off()

You can see how the rep3 vs rep4 comparison was totally ignored in head(P2$data[[3]], 20), see panel 1:

   x xend         y      yend annotation       group PANEL shape colour textsize angle hjust vjust alpha family fontface
1  1    1  5.035361  5.153492        foo rep1-rep2-1     1    19  black        5     0   0.5     0    NA               1
2  1    2  5.153492  5.153492        foo rep1-rep2-1     1    19  black        5     0   0.5     0    NA               1
3  2    2  5.153492  5.035361        foo rep1-rep2-1     1    19  black        5     0   0.5     0    NA               1
4  1    1  5.035361  5.153492        foo rep1-rep3-2     1    19  black        5     0   0.5     0    NA               1
5  1    3  5.153492  5.153492        foo rep1-rep3-2     1    19  black        5     0   0.5     0    NA               1
6  3    3  5.153492  5.035361        foo rep1-rep3-2     1    19  black        5     0   0.5     0    NA               1

And of course, the final plot doesn't show the bracket for that comparison (only for the rep1 comparisons):

test

Any idea why this is happening?

As an additional question: how would I specify the y_position for all the final brackets in all panels? I know how to do it if it's the same for all panels, but note Dcells Population has a different range of values, so I would like to keep the "free" scales.

Many thanks!

Upvotes: 1

Views: 3343

Answers (1)

jared_mamrot
jared_mamrot

Reputation: 26695

It looks like you need to move 'group = 1' into geom_line(), E.g.

library(tidyverse)
library(ggsignif)
mydata <- data.frame(Rep=rep(paste0('rep',1:5), 4),
                     Population=rep(paste0(LETTERS[1:4],'cells'), each=5),
                     Value=c(runif(15,1,5), runif(5, 30,40)))


P <- ggplot(mydata, aes(x = Rep, y = Value)) +
  geom_point(color = "red", shape = 16, size = 5) +
  geom_line(aes(group = 1)) +
  facet_wrap(. ~Population, scales = "free_y", ncol = 2) +
  theme_light() +
  geom_signif(comparisons=list(c("rep1", "rep2"),
                               c("rep1", "rep3"),
                               c("rep3", "rep4")),
              annotations = c("foo 1v2", "foo 1v3", "foo 3v4"),
              textsize=4,
              size=1,
              step_increase = 0.1)

# build the plot (get a list of data frames out of it)
P2 <- ggplot2::ggplot_build(P)
# in list 3 we have access to each annotation
head(P2$data[[3]], 20)
# plot
grDevices::pdf.options(reset = TRUE, onefile = FALSE)
grDevices::pdf(file="test.pdf", height=10, width=10)
print(#or ggsave()
  graphics::plot(ggplot2::ggplot_gtable(P2))
)
grDevices::dev.off()

example_1.png

You might want to consider changing the 'free y' scale too, depending on your application, E.g.

P <- ggplot(mydata, aes(x = Rep, y = Value)) +
  geom_point(color = "red", shape = 16, size = 5) +
  geom_line(aes(group = 1)) +
  facet_wrap(. ~Population, ncol = 2) +
  theme_light() +
  ylim(c(0,60)) +
  geom_signif(comparisons=list(c("rep1", "rep2"),
                               c("rep1", "rep3"),
                               c("rep3", "rep4")),
              annotations = c("foo 1v2", "foo 1v3", "foo 3v4"),
              textsize=4,
              size=1,
              step_increase = 0.1)

# build the plot (get a list of data frames out of it)
P2 <- ggplot2::ggplot_build(P)
# in list 3 we have access to each annotation
head(P2$data[[3]], 20)
# plot
grDevices::pdf.options(reset = TRUE, onefile = FALSE)
grDevices::pdf(file="test.pdf", height=10, width=10)
print(#or ggsave()
  graphics::plot(ggplot2::ggplot_gtable(P2))
)
grDevices::dev.off()

example_2.png

Upvotes: 2

Related Questions