Diff of /R/getMoHeatmap.R [000000] .. [494cbf]

Switch to unified view

a b/R/getMoHeatmap.R
1
#' @name getMoHeatmap
2
#' @title Get multi-omics comprehensive heatmap
3
#' @description  This function vertically concatenates multiple heatmap derived from each omics data. `getMoHeatmap` supports customized column annotation and is able to mark the selected features if indicated.
4
#' @param data A list of data frame or matrix storing multiple omics data with rows for features and columns for samples.
5
#' @param is.binary A logicial vector to indicate if the subdata is binary matrix of 0 and 1 such as mutation.
6
#' @param row.title A string vector to assign titles for each subdata.
7
#' @param legend.name A string vector to assign legend title for each subdata.
8
#' @param clust.res A clust.res object returned by `getMOIC()` with one specified algorithm or `get\%algorithm_name\%` or `getConsensusMOIC()` with a list of multiple algorithms.
9
#' @param clust.dend A dendrogram object returned returned by `getMOIC()` with one specified algorithm or `get\%algorithm_name\%` or `getConsensusMOIC()` with a list of multiple algorithms.
10
#' @param show.col.dend A logical vector to indicate if showing the dendrogram for column at the top of heatmap.
11
#' @param show.colnames A logical vector to indicate if showing the names for column at the bottom of heatmap.
12
#' @param show.row.dend A logical vector to indicate if showing the dendrogram for row of each subdata.
13
#' @param show.rownames A logical vector to indicate if showing the names for row of each subdata.
14
#' @param clust.dist.row A string vector to assign distance method for clustering each subdata at feature dimension.
15
#' @param clust.method.row A string vector to assign clustering method for clustering each subdata at feature dimension.
16
#' @param clust.col A string vector storing colors for annotating each subtype at the top of heatmap.
17
#' @param color A list of string vectors storing colors for each subheatmap of subdata.
18
#' @param annCol A data.frame storing annotation information for samples with exact the same sample order with data parameter.
19
#' @param annColors A list of string vectors for colors matched with annCol.
20
#' @param annRow A list of string vectors to indicate which features belong to which subdata should be annotated specifically in subheatmap.
21
#' @param width An integer value to indicate the width for each subheatmap with unit of cm.
22
#' @param height An integer value to indicate the height for each subheatmap with unit of cm.
23
#' @param fig.path A string value to indicate the output path for storing the comprehensive heatmap.
24
#' @param fig.name A string value to indicate the name of the comprehensive heatmap.
25
#' @return A pdf of multi-omics comprehensive heatmap
26
#' @importFrom ComplexHeatmap HeatmapAnnotation Heatmap rowAnnotation anno_mark draw ht_opt %v%
27
#' @importFrom ClassDiscovery distanceMatrix
28
#' @importFrom grDevices pdf dev.off colorRampPalette
29
#' @importFrom circlize colorRamp2
30
#' @importFrom dplyr %>%
31
#' @references Gu Z, Eils R, Schlesner M (2016). Complex heatmaps reveal patterns and correlations in multidimensional genomic data. Bioinformatics.
32
#' @export
33
#' @examples # There is no example and please refer to vignette.
34
getMoHeatmap <- function(data             = NULL,
35
                         is.binary        = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
36
                         row.title        = c("Data1","Data2","Data3","Data4","Data5","Data6"),
37
                         legend.name      = c("Data1","Data2","Data3","Data4","Data5","Data6"),
38
                         clust.res        = NULL,
39
                         clust.dend       = NULL,
40
                         show.col.dend    = TRUE,
41
                         show.colnames    = FALSE,
42
                         show.row.dend    = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE),
43
                         show.rownames    = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
44
                         clust.dist.row   = c("pearson","pearson","pearson","pearson","pearson","pearson"),
45
                         clust.method.row = c("ward.D","ward.D","ward.D","ward.D","ward.D","ward.D"),
46
                         clust.col        = c("#2EC4B6","#E71D36","#FF9F1C","#BDD5EA","#FFA5AB","#011627","#023E8A","#9D4EDD"),
47
                         color            = rep(list(c("#00FF00", "#000000", "#FF0000")),length(data)),
48
                         annCol           = NULL,
49
                         annColors        = NULL,
50
                         annRow           = NULL,
51
                         width            = 6,
52
                         height           = 4,
53
                         fig.path         = getwd(),
54
                         fig.name         = "moheatmap") {
55
56
  ht_opt$message = FALSE
57
  defaultW <- getOption("warn")
58
  options(warn = -1)
59
60
  # check data
61
  if(is.null(names(data))){
62
    names(data) <- sprintf("dat%s", 1:length(data))
63
  }
64
65
  n_dat <- length(data)
66
  if(n_dat > 6){
67
    stop('current verision of MOVICS can support up to 6 datasets.')
68
  }
69
  if(n_dat < 2){
70
    stop('current verision of MOVICS needs at least 2 omics data.')
71
  }
72
73
  colvec <- clust.col[1:length(unique(clust.res$clust))]
74
  names(colvec) <- paste0("CS",unique(clust.res$clust))
75
76
  if(!is.null(annCol) & !is.null(annColors)) {
77
78
    annCol <- annCol[colnames(data[[1]]), , drop = FALSE]
79
    annCol$Subtype <- paste0("CS",clust.res[colnames(data[[1]]),"clust"])
80
    annColors[["Subtype"]] <- colvec
81
82
    if(is.null(clust.dend)) {
83
      clust.res <- clust.res[order(clust.res$clust),]
84
      annCol <- annCol[clust.res$samID, , drop = FALSE]
85
    }
86
87
    ha <- ComplexHeatmap::HeatmapAnnotation(df     = annCol,
88
                                            col    = annColors,
89
                                            border = FALSE)
90
  } else {
91
    annCol <- data.frame("Subtype" = paste0("CS",clust.res[colnames(data[[1]]),"clust"]),
92
                         row.names = colnames(data[[1]]),
93
                         stringsAsFactors = FALSE)
94
    annColors <- list("Subtype" = colvec)
95
96
    if(is.null(clust.dend)) {
97
      clust.res <- clust.res[order(clust.res$clust),]
98
      annCol <- annCol[clust.res$samID,,drop = FALSE]
99
    }
100
101
    ha <- ComplexHeatmap::HeatmapAnnotation(df     = annCol,
102
                                            col    = annColors,
103
                                            border = FALSE)
104
    }
105
106
  if(!is.null(annRow)) {
107
    if(!is.list(annRow)) {stop("argument of annRow should be a list!")}
108
  }
109
110
  ht <- list()
111
  for (i in 1:n_dat) {
112
113
    hcg <- hclust(ClassDiscovery::distanceMatrix(as.matrix(t(data[[i]])), clust.dist.row[i]), clust.method.row[i])
114
115
    if(is.null(annRow[[i]][1])) {
116
      rowlab <- ""
117
      rowlab.index <- 0
118
    } else if (is.na(annRow[[i]][1])) {
119
      rowlab <- ""
120
      rowlab.index <- 0
121
    } else {
122
      rowlab <- intersect(rownames(data[[i]]),annRow[[i]])
123
      rowlab.index <- match(rowlab, rownames(data[[i]]))
124
    }
125
126
    if(is.null(clust.dend)) {
127
      data <- lapply(data, function(x) x[,clust.res$samID])
128
129
      if(!is.binary[i]) {
130
        ht[[i]] <-  ComplexHeatmap::Heatmap(matrix               = as.matrix(data[[i]]),
131
                                            row_title            = row.title[i],
132
                                            name                 = legend.name[i],
133
                                            cluster_columns      = FALSE,
134
                                            cluster_rows         = hcg,
135
                                            show_column_dend     = FALSE,
136
                                            show_column_names    = show.colnames,
137
                                            show_row_dend        = show.row.dend[i],
138
                                            show_row_names       = show.rownames[i],
139
                                            col                  = grDevices::colorRampPalette(color[[i]])(64),
140
                                            top_annotation       = switch((i == 1) + 1, NULL, ha),
141
                                            width                = grid::unit(width, "cm"),
142
                                            height               = grid::unit(height, "cm"),
143
                                            heatmap_legend_param = list(at     = pretty(range(data[[i]])),
144
                                                                        labels = pretty(range(data[[i]]))),
145
                                            right_annotation     = ComplexHeatmap::rowAnnotation(link =
146
                                                                                                   anno_mark(at         = rowlab.index,
147
                                                                                                             labels     = rowlab,
148
                                                                                                             which      = "row",
149
                                                                                                             lines_gp   = grid::gpar(fontsize = 5),
150
                                                                                                             link_width = grid::unit(3, "mm"),
151
                                                                                                             padding    = grid::unit(0.8, "mm"),
152
                                                                                                             labels_gp  = grid::gpar(fontsize = 7))))
153
      } else {
154
        col_fun = circlize::colorRamp2(c(0, 1), color[[i]])
155
156
        ht[[i]] <-  ComplexHeatmap::Heatmap(matrix               = as.matrix(data[[i]]),
157
                                            row_title            = row.title[i],
158
                                            name                 = legend.name[i],
159
                                            cluster_columns      = FALSE,
160
                                            cluster_rows         = hcg,
161
                                            show_column_dend     = FALSE,
162
                                            show_column_names    = show.colnames,
163
                                            show_row_dend        = show.row.dend[i],
164
                                            show_row_names       = show.rownames[i],
165
                                            col                  = color[[i]],
166
                                            top_annotation       = switch((i == 1) + 1, NULL, ha),
167
                                            width                = grid::unit(width, "cm"),
168
                                            height               = grid::unit(height, "cm"),
169
                                            heatmap_legend_param = list(at        = c(0, 1),
170
                                                                        legend_gp = grid::gpar(fill = col_fun(c(0,1))),
171
                                                                        labels    = c("0", "1")),
172
                                            right_annotation     = ComplexHeatmap::rowAnnotation(link =
173
                                                                                                   anno_mark(at         = rowlab.index,
174
                                                                                                             labels     = rowlab,
175
                                                                                                             which      = "row",
176
                                                                                                             lines_gp   = grid::gpar(fontsize = 5),
177
                                                                                                             link_width = grid::unit(3, "mm"),
178
                                                                                                             padding    = grid::unit(0.8, "mm"),
179
                                                                                                             labels_gp  = grid::gpar(fontsize = 7))))
180
      }
181
182
    } else {
183
      if(!is.binary[i]) {
184
        ht[[i]] <-  ComplexHeatmap::Heatmap(matrix               = as.matrix(data[[i]]),
185
                                            row_title            = row.title[i],
186
                                            name                 = legend.name[i],
187
                                            cluster_columns      = clust.dend,
188
                                            cluster_rows         = hcg,
189
                                            show_column_dend     = show.col.dend,
190
                                            show_column_names    = show.colnames,
191
                                            show_row_dend        = show.row.dend[i],
192
                                            show_row_names       = show.rownames[i],
193
                                            col                  = grDevices::colorRampPalette(color[[i]])(64),
194
                                            top_annotation       = switch((i == 1) + 1, NULL, ha),
195
                                            width                = grid::unit(width, "cm"),
196
                                            height               = grid::unit(height, "cm"),
197
                                            heatmap_legend_param = list(at     = pretty(range(data[[i]])),
198
                                                                        labels = pretty(range(data[[i]]))),
199
                                            right_annotation     = ComplexHeatmap::rowAnnotation(link =
200
                                                                                                   anno_mark(at         = rowlab.index,
201
                                                                                                             labels     = rowlab,
202
                                                                                                             which      = "row",
203
                                                                                                             lines_gp   = grid::gpar(fontsize = 5),
204
                                                                                                             link_width = grid::unit(3, "mm"),
205
                                                                                                             padding    = grid::unit(0.8, "mm"),
206
                                                                                                             labels_gp  = grid::gpar(fontsize = 7))))
207
      } else {
208
        col_fun = circlize::colorRamp2(c(0, 1), color[[i]])
209
210
        ht[[i]] <-  ComplexHeatmap::Heatmap(matrix               = as.matrix(data[[i]]),
211
                                            row_title            = row.title[i],
212
                                            name                 = legend.name[i],
213
                                            cluster_columns      = clust.dend,
214
                                            cluster_rows         = hcg,
215
                                            show_column_dend     = show.col.dend,
216
                                            show_column_names    = show.colnames,
217
                                            show_row_dend        = show.row.dend[i],
218
                                            show_row_names       = show.rownames[i],
219
                                            col                  = color[[i]],
220
                                            top_annotation       = switch((i == 1) + 1, NULL, ha),
221
                                            width                = grid::unit(width, "cm"),
222
                                            height               = grid::unit(height, "cm"),
223
                                            heatmap_legend_param = list(at        = c(0, 1),
224
                                                                        legend_gp = grid::gpar(fill = col_fun(c(0,1))),
225
                                                                        labels    = c("0", "1")),
226
                                            right_annotation     = ComplexHeatmap::rowAnnotation(link =
227
                                                                                                   anno_mark(at         = rowlab.index,
228
                                                                                                             labels     = rowlab,
229
                                                                                                             which      = "row",
230
                                                                                                             lines_gp   = grid::gpar(fontsize = 5),
231
                                                                                                             link_width = grid::unit(3, "mm"),
232
                                                                                                             padding    = grid::unit(0.8, "mm"),
233
                                                                                                             labels_gp  = grid::gpar(fontsize = 7))))
234
      }
235
    }
236
  }
237
238
  if(n_dat == 1){
239
    ht_list <- ht[[1]]
240
  }
241
  if(n_dat == 2){
242
    ht_list <- ht[[1]] %v% ht[[2]]
243
  }
244
  if(n_dat == 3){
245
    ht_list <- ht[[1]] %v% ht[[2]] %v% ht[[3]]
246
  }
247
  if(n_dat == 4){
248
    ht_list <- ht[[1]] %v% ht[[2]] %v% ht[[3]] %v% ht[[4]]
249
  }
250
  if(n_dat == 5){
251
    ht_list <- ht[[1]] %v% ht[[2]] %v% ht[[3]] %v% ht[[4]] %v% ht[[5]]
252
  }
253
  if(n_dat == 6){
254
    ht_list <- ht[[1]] %v% ht[[2]] %v% ht[[3]] %v% ht[[4]] %v% ht[[5]] %v% ht[[6]]
255
  }
256
257
  outFile <- file.path(fig.path,paste0(fig.name,".pdf"))
258
  if(is.null(annCol)) {
259
    pdf(outFile, width = width, height = height * n_dat/2)
260
  } else {
261
    pdf(outFile, width = width, height = height * n_dat/1.5)
262
  }
263
  draw(ht_list, merge_legend = TRUE, heatmap_legend_side = "right") # output to pdf
264
  invisible(dev.off())
265
266
  draw(ht_list, merge_legend = TRUE, heatmap_legend_side = "right") # output to screen
267
268
  options(warn = defaultW)
269
}