1

Hopefully this one is pretty easy, but I just can't seem to find the answer, though I have checked quite a few answers on here about flipping y-axes.

I have data like this:

df<-structure(list(applicant_name = structure(1:3, .Label = c("John Smith", 
"Lauren", "Billy"), class = "factor"), MeanRanking = c(11.5, 
8.25, 20)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", 
"data.frame"))

I have a graph like this:enter image description here

And I'd like to flip it upside down as a lower score is "better". From what I find on here, scale_y_reverse can flip it upside down, but then my bars are drawn from the top, like so:

enter image description here

How do I put 0 at the top, the largest number at the bottom (the real data might get bigger than 12, the bottom could be 20 I supposed because it couldn't be bigger than that) and draw the bars/columns from the bottom?

Edit: seems like per the comments/answers geom_col may not work, but my aesthetic goal would be: the "biggest and tallest" bar would actually be for the smallest number. In the real world, this will be the applicant that will have the best placing "ranked in top 3" and so it'd be great if it kinda looked like the top of the podium per se. If that makes sense This is what I'd like: enter image description here

Joe Crozier
  • 944
  • 8
  • 20
  • 1
    It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input that can be used to test and verify possible solutions. In ggplot bars always start at zero, you have to do a lot of work to make that not the case. If you don't want to start at zero, what number do you want to start at? Do you want to hard code a value? Are you sure a bar plot is the best visualization for your data? – MrFlick Nov 23 '20 at 17:01
  • @MrFlick added some data and clarification – Joe Crozier Nov 23 '20 at 17:18
  • @JoeCrozier could you draw by hand, how the output should look? And add to the question? – Duck Nov 23 '20 at 17:49
  • Thank you, just did – Joe Crozier Nov 23 '20 at 17:53

2 Answers2

1

I don't believe geom_col will work, because geom_col starts at 0 (or see this answer). We could use geom_segment instead, after doing a bit of data manipulation:

library(tidyverse) 

df %>%
    mutate(yy_max = max(MeanRanking)) %>%
    mutate(yy_min = yy_max - MeanRanking)  %>%
    ggplot(aes(applicant_name, yy_min, yend = yy_max, xend = applicant_name))+
    geom_segment(aes(colour = applicant_name), size = 3)+
    scale_y_reverse()

enter image description here

bouncyball
  • 10,631
  • 19
  • 31
  • This doesn't seem quite right as Lauren would now have the smallest bar and billy's would be way up near the top. But thank you for all the info – Joe Crozier Nov 23 '20 at 17:41
  • 2
    I'd suggest adding a picture of your expected output, even if it's just a sketch. It's unclear to mean what you're looking to achieve. – bouncyball Nov 23 '20 at 17:47
1

Maybe this can be close to what you want:

library(dplyr)
library(ggplot2)
library(tidyr)
#Code
df %>% mutate(Diff=abs(MeanRanking-max(MeanRanking))) %>%
  pivot_longer(-applicant_name) %>%
  mutate(value=-value,label=ifelse(name=='MeanRanking',abs(value),NA)) %>%
  ggplot(aes(x=applicant_name,y=value,fill=interaction(applicant_name,name)))+
  scale_y_continuous(labels = function(x) abs(x))+
  geom_bar(stat = 'identity')+
  geom_text(aes(label=label),vjust=-0.5,fontface='bold')+
  scale_fill_manual(values = c('tomato','cyan3','magenta',
                               'transparent','transparent','transparent'))+
  theme(legend.position = 'none')

Output:

enter image description here

Duck
  • 39,058
  • 13
  • 42
  • 84
  • This worked and as such I accepted your answer, but question: something about the code made it so the bar with the "lowest" score (in your example, Billy with a 20) never shows up. I added some other fake data to raise his average to a 17.5 and the scale of the whole graph changed so that 17.5 was at the bottom and he still didn't have a bar. I guess in my question I did say "largest number at the bottom", so that answers my question, but now having seen it, is there a way to always fix 20 at the bottom? – Joe Crozier Nov 23 '20 at 19:17
  • 1
    @JoeCrozier There is an option in `scale_y_continuous()` named `limits`. Play around that with `limits=c(NA,20)` or `limits=c(NA,-20)` – Duck Nov 23 '20 at 20:19