0

I am writing a function to plot heat map for users. In the following example, it plots the change of grade over time for different gender.

However, this is a special case. "Gender" may have other name like "Class". I will let user input their specific name and then make ggplot have the right label for each axis.

How do I modify my function "heatmap()" based on what I need?

sampledata <- matrix(c(1:60,1:60,rep(0:1,each=60),sample(1:3,120,replace = T)),ncol=3)
colnames(sampledata) <- c("Time","Gender","Grade")
sampledata <- data.frame(sampledata)
heatmap=function(sampledata,Gender)
{
sampledata$Time <- factor(sampledata$Time)
sampledata$Grade <- factor(sampledata$Grade)
sampledata$Gender <- factor(sampledata$Gender)
color_palette <- colorRampPalette(c("#31a354","#2c7fb8", "#fcbfb8","#f03b20"))(length((levels(factor(sampledata$Grade)))))
ggplot(data = sampledata) + geom_tile( aes(x = Time, y = Gender, fill = Grade))+scale_x_discrete(breaks = c("10","20","30","40","50"))+scale_fill_manual(values =color_palette,labels=c("0-1","1-2","2-3","3-4","4-5","5-6",">6"))+  theme_bw()+scale_y_discrete(labels=c("Female","Male"))
}
1
  • 1
    I think you need aes_string. Take a look at this and this Commented Jun 21, 2016 at 18:24

1 Answer 1

3

The easiest solution is redefining the function using aes_string. When the function is called, you need to pass it the name of the column you want to use as a string.

heatmap=function(sampledata,y)
{
        sampledata$Time <- factor(sampledata$Time)
        sampledata$Grade <- factor(sampledata$Grade)
        sampledata$new_var <- factor(sampledata[,y])
        color_palette <- colorRampPalette(c("#31a354","#2c7fb8", "#fcbfb8","#f03b20"))(length((levels(factor(sampledata$Grade)))))
        ggplot(data = sampledata) + geom_tile( aes_string(x = "Time", y = "new_var", fill = "Grade"))+scale_x_discrete(breaks = c("10","20","30","40","50"))+scale_fill_manual(values =color_palette,labels=c("0-1","1-2","2-3","3-4","4-5","5-6",">6"))+  theme_bw()+scale_y_discrete(labels=c("Female","Male")) + ylab(y)
}


# Below an example of how you call the newly defined function
heatmap(sampledata, "Gender")

Alternatively if you want to retain the quote free syntax, there is a slightly more complex solution:

heatmap=function(sampledata,y)
{
        arguments <- as.list(match.call())
        axis_label <- deparse(substitute(y))
        y = eval(arguments$y, sampledata)

        sampledata$Time <- factor(sampledata$Time)
        sampledata$Grade <- factor(sampledata$Grade)
        sampledata$y <- factor(y)
        color_palette <- colorRampPalette(c("#31a354","#2c7fb8", "#fcbfb8","#f03b20"))(length((levels(factor(sampledata$Grade)))))
        ggplot(data = sampledata) + geom_tile( aes(x = Time, y = y, fill = Grade))+scale_x_discrete(breaks = c("10","20","30","40","50"))+scale_fill_manual(values =color_palette,labels=c("0-1","1-2","2-3","3-4","4-5","5-6",">6"))+  theme_bw()+scale_y_discrete(labels=c("Female","Male")) + ylab(axis_label)
}

# Below an example of how you call the newly defined function
heatmap(sampledata, Gender)
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot! Just one more question: in the second function, we are still using 'sampledata$Gender <- factor(sampledata$Gender)' which includes Gender. It does't work if I put 'sampledata$y <- factor(sampledata$y)'. How to solve this part?
Yeah I forgot to change that part. I have edited both codes to make them more general. Now everything should work.
What if I want the label of y axis to be "Gender" instead of "new_var" and "y". (Gender is consistent with the user input, it can also be other names)
I have edited the code. Now the y label will have the same name as the variable you are passing to the function. In the first function you simply pass the variable name to ylab, since it is already a string. In the second there is a bit of extra code at the beginning to extract the name. I want more brownie points for this :P
Thanks a lot! That's really helpful. I have been searching around but couldn't figure it out. Now it works perfectly!

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.