0

I have been trying to create a plot containing a comparison of "N1", "NON-N1" groups in a specific order. My data contains different groups called "A", "N1", "NON-N1", "Comb", and I am trying to show first the group with all called "A", then the groups "N1", "NON-N1" in a specific order, and finally the group called "Comb". I would like to show the "N1" versus (on top of) "NON-N1" in all comparisons but I have failed with everything I have tried. I was also hoping to separate these groups using facet_wrap but it seems that the function does not work with coord_flip(). But that is even secondary as I have not even been able to solve my first problem. I can reorder the data frame but the ggplot does not obey. Please help me understand how to solve this. Thank you!

library(ggplot2)

df = structure(list(CI1 = c(-3.2, -2, -2.1, -4.4, -2.0, -2.0, -4.4, -2.0, -4.6, -4.6, -0.5, 2.3, 2.0, -2.0, 1.2, 0.01, 2.0), OR = c(-2.2, 2, -2.1, -2.4, 0.04, 0.004, -2.4, 0.26, -2.6, -2.6, 0.24, 2.4, 2.5, 0.02, 1.5, 0.15, 2.4), CI2 = c(4.34247, 5.05772, 4.96875, 5.26578, 1.91331, 1.87162, 3.78027, 4.55967, 4.07937, 4.50965, 3.54538, 3.97742, 3.5491, 2.41067, 2.73239, 2.3767, 3.55664), Label = structure(1:17, .Label = c("N1_A", "NON-N1_A", "N1_B", "NON-N1_B", "N1_C", "NON-N1_C", "N1_D", "NON-N1_H", "N1_H", "NON-N1_D", "N1_E", "NON-N1_E", "N1_F", "NON-N1_F", "N1_G", "NON-N1_G", "Comb"), class = "factor"), group = c("N1", "NON-N1", "N1", "NON-N1", "N1", "NON-N1", "N1", "NON-N1", "N1", "NON-N1", "N1", "NON-N1", "N1", "NON-N1", "A", "A", "Comb")), .Names = c("CI1", "OR", "CI2", "Label", "group"), class = "data.frame", row.names = c(12L, 4L, 8L, 11L, 10L, 13L, 9L, 5L, 6L, 7L, 3L, 2L, 1L, 14L, 17L, 16L, 18L))

# order wanted using the column "Label":
ordered.names = c("N1_G", "NON-N1_G", "N1_C", "NON-N1_C", "N1_F", "NON-N1_F", "N1_A", "NON-N1_A","N1_B", "NON-N1_B","N1_H", "NON-N1_H","N1_D", "NON-N1_D","N1_E", "NON-N1_E", "Comb")

df$group = factor(df$group, levels =c("A", "N1", "NON-N1", "Comb"))
# df <- transform(df, category2 = factor(Label))
df$Label = factor(df$Label, levels=ordered.names)
# df = df[order(df$Label),]
# df$Label <- factor(rev(df$Label), levels=rev(levels(df$Label)))

ggplot(df, aes(x=Label, y=OR, ymin=CI1, ymax=CI2, group=group, color=group)) + geom_pointrange() + coord_flip() 
# + facet_wrap(~group, scale="free_x")
jamespower
  • 15
  • 4

1 Answers1

1

Assuming your question is: How can you plot groups in a specific order (A, N1, NON-N1, Comb) from top to bottom.

First, helpful links:

  • How to order factor variables in ggplot2 by Kohske [link]
  • Order data frame by two columns [link]

The approach below uses both those links. First reorder your data according to group then Label (in descending order since you want Label displayed in reverse order (i.e. top to bottom after coord_flip()). Second, new factor Label2 is ordered according to appearance in the data frame.

df2 <- df[with(df, rev(order(Label, factor(group, Label)))),]  #Reverse reorder
df2$Label2 <- factor(df2$Label, as.character(df2$Label))       #Order of appearance

ggplot(df2, aes(x=Label2, y=OR, ymin=CI1, ymax=CI2, group=group, color=group)) + 
    geom_pointrange() + coord_flip()

Reorder factors in reverse order

Community
  • 1
  • 1
oshun
  • 2,319
  • 18
  • 32
  • Thank you very very much oshun! Is there any way that the exact order can be followed using the vector "ordered.names"? I am asking because my full dataset contains many more names within the N1/NON-N1 groups and they get rearranged not in the order I would like if I just use the "rev"... Also, is there any way that the groups (A, N1, NON-N1, Comb) can be separated in different sections (facet_wrap does not seem to work with coord_flip...)? Thank you again!! – jamespower Jan 31 '16 at 17:30
  • The y-axis is already ordered according to your vector "ordered.names" (based on the original code you wrote). Notice it is not in alphabetical order. I do not think you can facet_wrap with coord_flip. Here's how you can plot without coord_flip: `ggplot(df, aes(y = Label, x = OR, xmin = CI1, xmax = CI2)) + geom_errorbarh(height=0) + geom_point()`. If you want to facet_wrap, you probably need to have values for all combinations of groups and labels, leaving you with a lot of empty space in your graphs. You can also plot groups separately and play with grobs. – oshun Feb 01 '16 at 02:10
  • Thanks again oshun, this was my mistake as I had the data frame already ordered from my trials with match, but in reality the character vector ordered.names and the data frame is not ordered and it would be for example like this: ordered.names = c("N1_E", "NON-N1_E", "N1_D", "NON-N1_D", "N1_C", "NON-N1_C", "N1_F", "NON-N1_F", "N1_A", "NON-N1_A","N1_B", "NON-N1_B","N1_G", "NON-N1_G", "N1_H", "NON-N1_H", "Comb"). I don't want to change the example now because it would confuse your answer, but I am trying to have the plot follow the exact order of this vector, is this possible? Thanks so much! – jamespower Feb 01 '16 at 11:41
  • So you want your data displayed according to "ordered.names" and not by "group" then "ordered.names"? There's probably enough info in the answer and links to solve your revised question. If that's not what you're asking, probably best would be to ask a new question with a mock-up/photoshop of the results you want. Thank you, by the way, for posting a reproducible example. – oshun Feb 01 '16 at 19:53