I am trying to make a grouped barchart. I’ve reused an older script that worked before, however in that script i didn’t have to color based on conditions. This is what I am trying now and failing at.
I want the bars to be coloured based on the Condition and if the value is below or above 0
Example data:
library( ggplot2)
library(reshape2)
library(Rcpp)
prot_names <- c("Prot_A", "Prot_B","Prot_C")
Expression_Con_A <- c(-1,2,1)
Expression_Con_B <- c(-2,1.5,0.5)
df <- data.frame(prot_names, Expression_Con_A, Expression_Con_B)
melt_dat <- melt((df))
I’m imagining something like:
for (i in melt_dat$value) {
if (melt_dat$value[i] > 0 & melt_dat$variable== "ConA")
{melt_dat$color<- skyblue1}
else if (melt_dat$value[i] < 0 & melt_dat$variable== "ConA")
{melt_dat$color<- red1}
else if (melt_dat$value[i] > 0 & melt_dat$variable== "ConB")
{melt_dat$color<- skyblue4}
else if (melt_dat$value[i] < 0 & melt_dat$variable== "ConB")
{melt_dat$color<- red4}
}
However this gives me the folowing error:
Error in if (melt_dat$value[i] > 0 & melt_dat$variable == "ConA") { :
the condition has length > 1
ggplot2: how to color a graph by multiple variables
This worked in a way but it gave me my bars in a colour and the frame in another which is not what I want
I also tried putting in the colors by hand
g<-ggplot(melt_dat, aes(x=value, y=prot_names, fill=variable))+
geom_bar(stat='identity', position='dodge')+
scale_fill_manual(values = c("red1","skyblue1","red1","red4","skyblue4","red4")
which did not work either as it only colours by condition (only uses red1 and skyblue 1 independant of value>0)
>Solution :
You can use nested ifelse (or if_else), but in case of multiple conditions it’d be easier to use case_when from dplyr, In your case:
library(dplyr)
melt_dat <- melt_dat %>% mutate("type" = case_when(value > 0 & variable == "Expression_Con_A" ~ "color1",
value < 0 & variable == "Expression_Con_A" ~ "color2",
value > 0 & variable == "Expression_Con_B" ~ "color3",
value < 0 & variable == "Expression_Con_B" ~ "color4"))
ggplot(melt_dat, aes(x=value, y=prot_names, fill=type)) +
geom_bar(stat='identity', position='dodge') +
scale_fill_manual(values = c("red1","skyblue1","red1","red4","skyblue4","red4"))
I defined a new variable "type", and note that in the ggplot you’ve to change the "fill" argument from "variable" to this new variable.