4

I have the following data which I am trying to plot as combined bar and line plot (with CI)

A data frame of Feature, Count, Odds Ratio and Confidence Interval values for OR A data frame of Feature, Count, Odds Ratio and Confidence Interval values for OR

I am trying to get a plot as A bar plot for count over lapped with a line plot for Odds Ratio with CI bars

A bar plot for count over lapped with a line plot for Odds Ratio with CI bars

I tried to plot in ggplot2 using following code:

ggplot(feat)+
  geom_bar(aes(x=Feat, y=Count),stat="identity", fill = "steelblue") +
  geom_line(aes(x=Feat, y=OR*max(feat$Count)),stat="identity", group = 1) +
  geom_point(aes(x=Feat, y=OR*max(feat$Count))) +
  geom_errorbar(aes(x=Feat, ymin=CI1, ymax=CI2), width=.1, colour="orange", 
                position = position_dodge(0.05))

However, I am not getting the CI bars for the line graph, as can be seen in pic: Rather, I am getting them for barplot Rather, I am getting them for barplot

Can someone can please help me out to sort this issue.

Thanks

Edit - Dput:

df <- structure(list(Feat = structure(1:8, .Label = c("A", "B", "C", 
"D", "E", "F", "G", "H"), class = "factor"), Count = structure(c(2L, 
8L, 7L, 5L, 4L, 1L, 6L, 3L), .Label = c("13", "145", "2", "25", 
"26", "3", "37", "43"), class = "factor"), OR = structure(c(4L, 
2L, 1L, 5L, 3L, 7L, 6L, 8L), .Label = c("0.38", "1.24", "1.33", 
"1.51", "1.91", "2.08", "2.27", "3.58"), class = "factor"), CI1 = structure(c(7L, 
4L, 1L, 6L, 3L, 5L, 2L, 2L), .Label = c("0.26", "0.43", "0.85", 
"0.89", "1.2", "1.24", "1.25"), class = "factor"), CI2 = structure(c(3L, 
2L, 1L, 6L, 4L, 7L, 8L, 5L), .Label = c("0.53", "1.7", "1.82", 
"1.98", "13.07", "2.83", "3.92", "6.13"), class = "factor")), class = "data.frame", row.names = c(NA, 
-8L))
2
  • 1
    Can you edit your post to include dput(feat) Commented Apr 2, 2020 at 23:05
  • What's the reference group for your odds ratios? Commented Apr 2, 2020 at 23:15

1 Answer 1

7

Is this what you had in mind?

ratio <- max(feat$Count)/max(feat$CI2)
ggplot(feat) +
  geom_bar(aes(x=Feat, y=Count),stat="identity", fill = "steelblue") +
  geom_line(aes(x=Feat, y=OR*ratio),stat="identity", group = 1) +
  geom_point(aes(x=Feat, y=OR*ratio)) +
  geom_errorbar(aes(x=Feat, ymin=CI1*ratio, ymax=CI2*ratio), width=.1, colour="orange", 
                position = position_dodge(0.05)) +
    scale_y_continuous("Count", sec.axis = sec_axis(~ . / ratio, name = "Odds Ratio"))

enter image description here

Edit: Just for fun with the legend too.

ggplot(feat) +
  geom_bar(aes(x=Feat, y=Count, fill = "Count"),stat="identity") + scale_fill_manual(values="steelblue") +
  geom_line(aes(x=Feat, y=OR*ratio, color = "Odds Ratio"),stat="identity", group = 1) + scale_color_manual(values="orange") +
  geom_point(aes(x=Feat, y=OR*ratio)) +
  geom_errorbar(aes(x=Feat, ymin=CI1*ratio, ymax=CI2*ratio), width=.1, colour="orange", 
                position = position_dodge(0.05)) +
  scale_y_continuous("Count", sec.axis = sec_axis(~ . / ratio, name = "Odds Ratio")) +  
  theme(legend.key=element_blank(), legend.title=element_blank(), legend.box="horizontal",legend.position = "bottom")

enter image description here

Since you asked about adding p values for comparisons in the comments, here is a way you can do that. Unfortunately, because you don't really want to add **all* the comparisons, there's a little bit of hard coding to do.

library(ggplot2)
library(ggsignif)
ggplot(feat,aes(x=Feat, y=Count)) +
  geom_bar(aes(fill = "Count"),stat="identity") + scale_fill_manual(values="steelblue") +
  geom_line(aes(x=Feat, y=OR*ratio, color = "Odds Ratio"),stat="identity", group = 1) + scale_color_manual(values="orange") +
  geom_point(aes(x=Feat, y=OR*ratio)) +
  geom_errorbar(aes(x=Feat, ymin=CI1*ratio, ymax=CI2*ratio), width=.1, colour="orange", 
                position = position_dodge(0.05)) +
  scale_y_continuous("Count", sec.axis = sec_axis(~ . / ratio, name = "Odds Ratio")) +  
  theme(legend.key=element_blank(), legend.title=element_blank(), legend.box="horizontal",legend.position = "bottom") + 
  geom_signif(comparisons = list(c("A","H"),c("B","F"),c("D","E")),
              y_position = c(150,60,40),
              annotation = c("***","***","n.s."))

enter image description here

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Ian that helped a lot. Can we add "st", "stst", "ststst" for OR p-values <.05, <.01 and <.001 respectively using nested if else loop. I tried but it didn't worked for some silly mistake (st - "") if (feat$pval < 0.001) { p + annotate("text", y = 250, label = "stststst", size = 8) } else { if (feat$pval < 0.01) { p + annotate("text", y = 250, label = "*", size = 8) } else { if (feat$pval < 0.05) { p + annotate("text", y = 250, label = "*", size = 8) } else { p + annotate("text", y = 250, label = "n.s", size = 8) } } p }
I edited with some p value annotations. It doesn't really lend itself to adding with a method, otherwise you just have a bunch of overlapping comparison bars.
Thanks Ian. Since, all the Feat are independent variables I cannot compare them. I am interested to show significance of each OR for each OR point, as mentioned in the edited graph. That is why I am trying an if-else loop.
I think I figured it out. I just need another column as 'sign' with assigned stars for significance in the data frame: feat$labs = c('','n.s','','','n.s','','n.s','n.s') and then add them as geom_text to graph: + geom_text(aes(x=Feat, y=300, label=labs), size=5, hjust=0.5, vjust = 1)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.