rheatmappheatmap

Add a gap in heatmap with pheatmap package


I made the heatmap using the code below:

library(pheatmap)
library(dplyr)

data = data.frame(matrix(runif(10*10), ncol=10))
data$sample = rep(c("tumour", "normal"), 5)
data$subject.ID = paste('Subject', 1:10)
data = data %>% arrange(sample)

# for row annotation
my_sample_col = data %>% select(sample)
rownames(my_sample_col) = data$subject.ID
# data matrix
mat = as.matrix(data %>% select(-sample, -subject.ID))
rownames(mat) = data$subject.ID

pheatmap(mat,
         scale='row',
         annotation_row = my_sample_col,
         annotation_names_row=F,
         cluster_rows = FALSE,
         cluster_cols = FALSE,
         show_colnames = FALSE,
         show_rownames = FALSE)

I want to put a gap between row 5 and row 6, to separate the heatmap according to my row annotation.

In pheatmap function, the argument gaps_row seems to do the job.

vector of row indices that show shere to put gaps into heatmap. Used only if the rows are not clustered.

I'm not sure how to implement that. Can someone help me with this? Thanks a lot.


Solution

  • I would recommend using ComplexHeatmap package (website; Gu et al, 2016). You can install it with devtools::install_github("jokergoo/ComplexHeatmap").

    It has more functionalities, but you also have to invest more time (eg., row annotation and matrix scaling).

    library(ComplexHeatmap)
    
    # Create annotation for rows
    my_sample_col_ano <- rowAnnotation(sample = my_sample_col$sample,
                                       show_annotation_name = FALSE)
    
    # Scale original matrix row-wise
    matS <- t(apply(mat, 1, scale))
    
    # Plot heatmap
    Heatmap(matS, 
            # Remove name from fill legend
            name = "",
            # Keep original row/col order
            row_order = rownames(matS), column_order = colnames(matS),
            # Add left annotation (legend with tumor/normal) 
            left_annotation = my_sample_col_ano,
            # ACTUAL SPLIT by sample group 
            row_split = my_sample_col$sample,
            show_row_names = FALSE, show_column_names = FALSE,
            show_row_dend = FALSE, show_column_dend = FALSE,
            row_title = NULL)
    

    enter image description here

    If you want to use original pheatmap pass argument to gaps_row which is equal to the size of your group (ie, normal):

    pheatmap(mat,
             scale='row',
             gaps_row = 5,
             annotation_row = my_sample_col,
             annotation_names_row=F,
             cluster_rows = FALSE,
             cluster_cols = FALSE,
             show_colnames = FALSE,
             show_rownames = FALSE)
    

    If you can more groups than two instead of hardcoding numeric value to gaps_row (ie, gaps_row = 5) you can pass this snippet (head(as.numeric(cumsum(table(my_sample_col$sample))), -1)).

    enter image description here