|
115 | 115 | circlize::colorRamp2(c(-m, 0, m), c("green", "black", "red")) |
116 | 116 | } |
117 | 117 |
|
| 118 | +.finite_heatmap_dist <- function(matrix) { |
| 119 | + tryCatch( |
| 120 | + { |
| 121 | + distance <- stats::dist(matrix) |
| 122 | + if (any(!is.finite(distance))) { |
| 123 | + return(NULL) |
| 124 | + } |
| 125 | + distance |
| 126 | + }, |
| 127 | + error = function(e) NULL |
| 128 | + ) |
| 129 | +} |
| 130 | + |
| 131 | +.can_cluster_heatmap_columns <- function(matrix) { |
| 132 | + if (ncol(matrix) < 2) { |
| 133 | + return(FALSE) |
| 134 | + } |
| 135 | + !is.null(.finite_heatmap_dist(t(matrix))) |
| 136 | +} |
| 137 | + |
| 138 | +.cluster_heatmap_rows <- function(matrix) { |
| 139 | + if (nrow(matrix) < 3) { |
| 140 | + return(matrix) |
| 141 | + } |
| 142 | + distance <- .finite_heatmap_dist(matrix) |
| 143 | + if (is.null(distance)) { |
| 144 | + return(matrix) |
| 145 | + } |
| 146 | + matrix[stats::hclust(distance)$order, , drop = FALSE] |
| 147 | +} |
| 148 | + |
118 | 149 | # White-to-red color function for correlation heatmaps, ranging over the |
119 | 150 | # observed values (R-squared lives in [0, 1]). |
120 | 151 | .cor_col_fun <- function(cres, R2 = FALSE) { |
@@ -500,50 +531,33 @@ plot_heatmap <- function( |
500 | 531 | } |
501 | 532 |
|
502 | 533 | resdata <- t(scale(t(matrix))) |
503 | | - resdataf <- prolfqua::remove_na_rows(resdata, floor(ncol(resdata) * na_fraction)) |
504 | | - |
505 | | - if (nrow(resdataf) >= 3) { |
506 | | - gg <- stats::hclust(stats::dist(resdataf)) |
507 | | - plot_data <- resdataf[gg$order, ] |
508 | | - res <- ComplexHeatmap::Heatmap( |
509 | | - plot_data, |
510 | | - name = "row z-score", |
511 | | - col = .abundance_col_fun(plot_data), |
512 | | - na_col = .HEATMAP_NA_COL, |
513 | | - cluster_rows = FALSE, |
514 | | - cluster_columns = TRUE, |
515 | | - top_annotation = .heatmap_top_annotation(annotation, factor_keys, sample_name, colnames(plot_data)), |
516 | | - show_row_names = show_rownames, |
517 | | - show_column_names = TRUE, |
518 | | - row_labels = .truncate_plot_labels(rownames(plot_data), max_rownames_chars), |
519 | | - column_labels = .suffix_plot_labels(colnames(plot_data), max_sample_label_chars), |
520 | | - border = FALSE, |
521 | | - use_raster = FALSE, |
522 | | - heatmap_legend_param = list(title = "row z-score"), |
523 | | - ... = ... |
524 | | - ) |
| 534 | + na_threshold <- floor(ncol(resdata) * na_fraction) |
| 535 | + keep_rows <- rowSums(is.na(resdata)) <= na_threshold |
| 536 | + resdataf <- resdata[keep_rows, , drop = FALSE] |
| 537 | + plot_data <- if (nrow(resdataf) >= 3) { |
| 538 | + .cluster_heatmap_rows(resdataf) |
525 | 539 | } else { |
526 | | - res <- tryCatch( |
527 | | - ComplexHeatmap::Heatmap( |
528 | | - resdata, |
529 | | - name = "row z-score", |
530 | | - col = .abundance_col_fun(resdata), |
531 | | - na_col = .HEATMAP_NA_COL, |
532 | | - cluster_rows = FALSE, |
533 | | - cluster_columns = TRUE, |
534 | | - top_annotation = .heatmap_top_annotation(annotation, factor_keys, sample_name, colnames(resdata)), |
535 | | - show_row_names = show_rownames, |
536 | | - show_column_names = TRUE, |
537 | | - row_labels = .truncate_plot_labels(rownames(resdata), max_rownames_chars), |
538 | | - column_labels = .suffix_plot_labels(colnames(resdata), max_sample_label_chars), |
539 | | - border = FALSE, |
540 | | - use_raster = FALSE, |
541 | | - heatmap_legend_param = list(title = "row z-score"), |
542 | | - ... = ... |
543 | | - ), |
544 | | - error = .error_handler # nolint object_usage_linter. defined in utilities.R |
545 | | - ) |
| 540 | + resdata |
546 | 541 | } |
| 542 | + cluster_columns <- .can_cluster_heatmap_columns(plot_data) |
| 543 | + |
| 544 | + res <- ComplexHeatmap::Heatmap( |
| 545 | + plot_data, |
| 546 | + name = "row z-score", |
| 547 | + col = .abundance_col_fun(plot_data), |
| 548 | + na_col = .HEATMAP_NA_COL, |
| 549 | + cluster_rows = FALSE, |
| 550 | + cluster_columns = cluster_columns, |
| 551 | + top_annotation = .heatmap_top_annotation(annotation, factor_keys, sample_name, colnames(plot_data)), |
| 552 | + show_row_names = show_rownames, |
| 553 | + show_column_names = TRUE, |
| 554 | + row_labels = .truncate_plot_labels(rownames(plot_data), max_rownames_chars), |
| 555 | + column_labels = .suffix_plot_labels(colnames(plot_data), max_sample_label_chars), |
| 556 | + border = FALSE, |
| 557 | + use_raster = FALSE, |
| 558 | + heatmap_legend_param = list(title = "row z-score"), |
| 559 | + ... = ... |
| 560 | + ) |
547 | 561 | invisible(res) |
548 | 562 | } |
549 | 563 |
|
|
0 commit comments