How to use conditional statement to colour barplot

Viewed 1033

I'm trying to colour geom_bar according to the number of the sample ifelse(total > 90, "#FC2D00", "#008EFC"). In other words, if the total > 90, the bar should be red but total < 90, it should be blue.

type = c("aa", "bb", "cc")
total = c(110, 90, 89)

df = data.frame(type, total)

df %>% 
ggplot2::ggplot(aes(x = type, y = total)) +
  geom_bar(position = "dodge",
           stat = "identity")

I tried

df %>% 
ggplot2::ggplot(aes(x = type, y = total)) +
  geom_bar(position = "dodge",
           stat = "identity",
           fill = (ifelse(
           levels(studies$total > 90, "#FC2D00", "#008EFC"))))

and also

df %>% 
mutate(fill = ifelse(levels(total > 90, "#FC2D00", "#008EFC"))) %>% 
ggplot2::ggplot(aes(x = type, y = total)) +
  geom_bar(position = "dodge",
           stat = "identity",
           fill = fill)

but it still not working. I'm not sure what is the problem.

3 Answers

There is no need of ifelse() or mutate(). You can directly use the logical condition inside fill and then format using scale_fill_manual() for the colors and labels:

library(ggplot2)
library(dplyr)
#Data
type = c("aa", "bb", "cc")
total = c(110, 90, 89)
df = data.frame(type, total)
#Plot
df %>% 
  ggplot2::ggplot(aes(x = type, y = total,fill=total > 90)) +
  geom_bar(position = "dodge",
           stat = "identity")+
  scale_fill_manual(values = c("#FC2D00","#008EFC"),
                    labels=c('TRUE'='>90','FALSE'='<90'))+
  labs(fill='Total')

Output:

enter image description here

Move your fill inside of the aes().

You should specify the colors in scale_fill_manual():

df %>% 
mutate(fill = ifelse(levels(total > 90, "#FC2D00", "#008EFC"))) %>% 
ggplot2::ggplot(aes(x = type, y = total, fill = fill)) +
  geom_bar(position = "dodge",
           stat = "identity") +
  scale_fill_manual(values= c("red","blue"))

In ggplot, we normally define color values in the scales, and legends are nicely autogenerated based on the data. So put in the data what you would want the legend labels to be, not the colors you want used.

df %>% 
mutate(emphasize = ifelse(total > 90, "> 90", "<= 90")) %>% 
ggplot(aes(x = type, y = total, fill = emphasize)) +
  geom_col(position = "dodge") +
  scale_fill_manual(values = c("> 90" = "#FC2D00", "<= 90" = "#008EFC"))

We don't need to use levels() - it's a bad choice here because total is not a factor (and it doesn't return one value per row, it may have a different order than the data...). I also switched geom_bar to geom_col - geom_col has stat = "identity" as the default.

Related