Abdel
Abdel

Reputation: 6106

Reorder does not work after adding second geom_points

My data looks like this:

> head(GEE)

  trait   beta   se       p   analysis signif
1 trait1  0.078 0.01 9.0e-13  group1   1
2 trait2  0.076 0.01 1.7e-11  group1   1
3 trait3  0.063 0.01 1.8e-08  group1   1
4 trait4  0.013 0.01 .06      group1   0
5 trait5  0.018 0.01 .54      group1   0
6 trait6 -0.014 0.01 .64      group1   0

I'm trying to make a plot with gglot2 of points and errorbars that are ordered on the second column named beta. That works fine with the following code:

ggplot(GEE, aes(y=beta, x=reorder(trait, beta), group=analysis)) + 
  geom_point(aes(color=analysis)) +
  geom_errorbar(aes(ymin=beta-2*se, ymax=beta+2*se,color=analysis), width=.2,
                position=position_dodge(.9)) +
  theme_light() +
  coord_flip() 

However, I want to add asterisks for significant points, for which I have an additional piece of code, that successfully adds asterisks to significant points:

geom_point(data = GEE[GEE$signif == 1, ],
           color="red",
           shape = "*", 
           size=12, 
           show.legend = F) +

When adding it to the previous plot command above, the full command looks like this:

ggplot(GEE, aes(y=beta, x=reorder(trait, beta), group=analysis)) + 
  geom_point(data = GEE[GEE$signif == 1, ],
             color="red",
             shape = "*", 
             size=12, 
             show.legend = F) +
  geom_point(aes(color=analysis)) +
  geom_errorbar(aes(ymin=beta-2*se, ymax=beta+2*se,color=analysis), width=.2,
                position=position_dodge(.9)) +
  theme_light() +
  coord_flip() 

The problem with the code after adding the asterisks however is that it somehow cancels the re-ordering that I specified with "x=reorder(trait, beta)". The order is now completely different. Why? :'(

UPDATE: @Lamia noted in the comments that the problem could not be re-produced with the data that is presented in this post. The data in this post only shows the top rows which are all from the same group (group1, see column "analysis"), but in my full dataset there are three groups. The ggplot2 command plots these three different groups with different colors. I can only reproduce the problem when I read in the full dataset with all three groups, so it seems that that may have something to do with this problem...

UPDATE 2: As @Lamia suggested (sorry, should have done this to begin with), I have added data below that reproduces the problem:

trait,beta,se,p,analysis,signif
trait1,0.078,0.01,9.00E-13,group1,1
trait2,0.076,0.01,1.70E-11,group1,1
trait3,-0.032,0.01,0.004,group1,0
trait4,0.026,0.01,0.024,group1,0
trait5,0.023,0.01,0.037,group1,0
trait1,0.042,0.01,4.50E-04,group2,1
trait2,0.04,0.01,0.002,group2,1
trait3,0.03,0.01,0.025,group2,0
trait4,0.025,0.01,0.078,group2,0
trait5,0.015,0.01,0.294,group2,0
trait1,0.02,0.01,0.078,group3,0
trait2,0.03,0.01,0.078,group3,0
trait3,0.043,0.01,1.90E-04,group3,0
trait4,0.043,0.01,2.40E-04,group3,1
trait5,0.029,0.01,0.013,group3,0

Upvotes: 0

Views: 251

Answers (2)

Z.Lin
Z.Lin

Reputation: 29085

Several suggestions for consideration...

1: Wrangle your data frame before feeding it into ggplot(). Since trait is a categorical variable, you can specify its levels as a factor explicitly.

library(dplyr)

g2 <- GEE %>%
  mutate(trait = factor(trait, levels = trait[order(beta[analysis == "group1"])]))

> levels(g2$trait)
[1] "trait3" "trait5" "trait4" "trait2" "trait1"

We can visually verify that the order of traits according to group 1's beta values are 3-5-4-2-1:

ggplot(GEE, aes(x = beta, y = analysis, label = trait)) + geom_label()

plot1

2: Use only one data source for ggplot(), if possible. This ensures that all the aesthetic mapping linkages are consistent, & is also simpler to maintain.

ggplot(g2, aes(y = beta, x = trait, group = analysis, color = analysis,
               ymin = beta - 2*se, ymax = beta + 2*se)) + 
  geom_point(aes(alpha = signif),   # hide non-significant points while using the same dataset
             color = "red") +       # override 'color = analysis' in ggplot()
  geom_point() +
  geom_errorbar() +
  scale_alpha_identity()

3: Reuse the same position_dodge() for all relevant geoms. Again, this is simpler to maintain should you wish to change the dodge width next time.

pd <- position_dodge(0.9)

ggplot(g2, aes(y = beta, x = trait, group = analysis, color = analysis,
               ymin = beta - 2*se, ymax = beta + 2*se)) + 
  geom_point(aes(alpha = signif), 
             color = "red", shape = "*", size = 12, show.legend = F,
             position = pd) +
  geom_point(position = pd) +
  geom_errorbar(width=.2, position = pd) +
  scale_alpha_identity() +
  theme_light() +
  coord_flip() 

Result (trait is sorted as 3-5-4-2-1, from bottom to top):

plot2

Data:

GEE <- read.csv(
  text = 
"trait,beta,se,p,analysis,signif
trait1,0.078,0.01,9.00E-13,group1,1
trait2,0.076,0.01,1.70E-11,group1,1
trait3,-0.032,0.01,0.004,group1,0
trait4,0.026,0.01,0.024,group1,0
trait5,0.023,0.01,0.037,group1,0
trait1,0.042,0.01,4.50E-04,group2,1
trait2,0.04,0.01,0.002,group2,1
trait3,0.03,0.01,0.025,group2,0
trait4,0.025,0.01,0.078,group2,0
trait5,0.015,0.01,0.294,group2,0
trait1,0.02,0.01,0.078,group3,0
trait2,0.03,0.01,0.078,group3,0
trait3,0.043,0.01,1.90E-04,group3,0
trait4,0.043,0.01,2.40E-04,group3,1
trait5,0.029,0.01,0.013,group3,0")

> levels(GEE$trait) # default order is 1-2-3-4-5
[1] "trait1" "trait2" "trait3" "trait4" "trait5"

Upvotes: 2

tyluRp
tyluRp

Reputation: 4768

Try this:

library(tidyverse)

GEE <- tribble(
  ~trait, ~beta, ~se, ~p, ~analysis, ~signif,
  "trait1", 0.078, 0.01, 9.0e-13, "group1", 1,
  "trait2", 0.076, 0.01, 1.7e-11, "group1", 1,
  "trait3", 0.063, 0.01, 1.8e-08, "group1", 1,
  "trait4", 0.013, 0.01, .06, "group1", 0,
  "trait5", 0.018, 0.01, .54, "group1", 0,
  "trait6", -0.014, 0.01, .64, "group1", 0
  )

GEE %>% 
  ggplot(aes(y = beta, x = reorder(trait, beta)), group = analysis) +
  geom_point(aes(color = analysis)) +
  geom_errorbar(aes(ymin = beta - 2 * se,
                    ymax = beta + 2 * se,
                    color = analysis,
                    width = 0.2),
                position = position_dodge(0.9)) +
  geom_point(data = GEE[GEE$signif == 1, ],
             color="red",
             shape = "*", 
             size=12, 
             show.legend = F) +
  theme_light() +
  coord_flip()

It changes this plot:

enter image description here

And makes it look like this:

enter image description here

Is that what you're looking for?

Upvotes: 1

Related Questions