-
-
Save RNAer/5242792 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # EXAMPLE USAGE | |
| # example of colsidecolors rowsidecolors (single column, single row) | |
| mat <- matrix(1:100, byrow=T, nrow=10) | |
| column_annotation <- sample(c("red", "blue", "green"), 10, replace=T) | |
| column_annotation <- as.matrix(column_annotation) | |
| colnames(column_annotation) <- c("Variable X") | |
| row_annotation <- sample(c("red", "blue", "green"), 10, replace=T) | |
| row_annotation <- as.matrix(t(row_annotation)) | |
| rownames(row_annotation) <- c("Variable Y") | |
| heatmap.3(mat, RowSideColors=row_annotation, ColSideColors=column_annotation) | |
| # multiple column and row | |
| mat <- matrix(1:100, byrow=T, nrow=10) | |
| column_annotation <- matrix(sample(c("red", "blue", "green"), 20, replace=T), ncol=2) | |
| colnames(column_annotation) <- c("Variable X1", "Variable X2") | |
| row_annotation <- matrix(sample(c("red", "blue", "green"), 20, replace=T), nrow=2) | |
| rownames(row_annotation) <- c("Variable Y1", "Variable Y2") | |
| heatmap.3(mat, RowSideColors=row_annotation, ColSideColors=column_annotation) | |
| # CODE | |
| heatmap.3 <- function(x, | |
| Rowv = TRUE, Colv = if (symm) "Rowv" else TRUE, | |
| distfun = dist, | |
| hclustfun = hclust, | |
| dendrogram = c("both","row", "column", "none"), | |
| symm = FALSE, | |
| scale = c("none","row", "column"), | |
| na.rm = TRUE, | |
| revC = identical(Colv,"Rowv"), | |
| add.expr, | |
| breaks, | |
| symbreaks = max(x < 0, na.rm = TRUE) || scale != "none", | |
| col = "heat.colors", | |
| colsep, | |
| rowsep, | |
| sepcolor = "white", | |
| sepwidth = c(0.05, 0.05), | |
| cellnote, | |
| notecex = 1, | |
| notecol = "cyan", | |
| na.color = par("bg"), | |
| trace = c("none", "column","row", "both"), | |
| tracecol = "cyan", | |
| hline = median(breaks), | |
| vline = median(breaks), | |
| linecol = tracecol, | |
| margins = c(5,5), | |
| ColSideColors, | |
| RowSideColors, | |
| side.height.fraction=0.3, | |
| cexRow = 0.2 + 1/log10(nr), | |
| cexCol = 0.2 + 1/log10(nc), | |
| labRow = NULL, | |
| labCol = NULL, | |
| key = TRUE, | |
| keysize = 1.5, | |
| density.info = c("none", "histogram", "density"), | |
| denscol = tracecol, | |
| symkey = max(x < 0, na.rm = TRUE) || symbreaks, | |
| densadj = 0.25, | |
| main = NULL, | |
| xlab = NULL, | |
| ylab = NULL, | |
| lmat = NULL, | |
| lhei = NULL, | |
| lwid = NULL, | |
| NumColSideColors = 1, | |
| NumRowSideColors = 1, | |
| KeyValueName="Value",...){ | |
| invalid <- function (x) { | |
| if (missing(x) || is.null(x) || length(x) == 0) | |
| return(TRUE) | |
| if (is.list(x)) | |
| return(all(sapply(x, invalid))) | |
| else if (is.vector(x)) | |
| return(all(is.na(x))) | |
| else return(FALSE) | |
| } | |
| x <- as.matrix(x) | |
| scale01 <- function(x, low = min(x), high = max(x)) { | |
| x <- (x - low)/(high - low) | |
| x | |
| } | |
| retval <- list() | |
| scale <- if (symm && missing(scale)) | |
| "none" | |
| else match.arg(scale) | |
| dendrogram <- match.arg(dendrogram) | |
| trace <- match.arg(trace) | |
| density.info <- match.arg(density.info) | |
| if (length(col) == 1 && is.character(col)) | |
| col <- get(col, mode = "function") | |
| if (!missing(breaks) && (scale != "none")) | |
| warning("Using scale=\"row\" or scale=\"column\" when breaks are", | |
| "specified can produce unpredictable results.", "Please consider using only one or the other.") | |
| if (is.null(Rowv) || is.na(Rowv)) | |
| Rowv <- FALSE | |
| if (is.null(Colv) || is.na(Colv)) | |
| Colv <- FALSE | |
| else if (Colv == "Rowv" && !isTRUE(Rowv)) | |
| Colv <- FALSE | |
| if (length(di <- dim(x)) != 2 || !is.numeric(x)) | |
| stop("`x' must be a numeric matrix") | |
| nr <- di[1] | |
| nc <- di[2] | |
| if (nr <= 1 || nc <= 1) | |
| stop("`x' must have at least 2 rows and 2 columns") | |
| if (!is.numeric(margins) || length(margins) != 2) | |
| stop("`margins' must be a numeric vector of length 2") | |
| if (missing(cellnote)) | |
| cellnote <- matrix("", ncol = ncol(x), nrow = nrow(x)) | |
| if (!inherits(Rowv, "dendrogram")) { | |
| if (((!isTRUE(Rowv)) || (is.null(Rowv))) && (dendrogram %in% | |
| c("both", "row"))) { | |
| if (is.logical(Colv) && (Colv)) | |
| dendrogram <- "column" | |
| else dedrogram <- "none" | |
| warning("Discrepancy: Rowv is FALSE, while dendrogram is `", | |
| dendrogram, "'. Omitting row dendogram.") | |
| } | |
| } | |
| if (!inherits(Colv, "dendrogram")) { | |
| if (((!isTRUE(Colv)) || (is.null(Colv))) && (dendrogram %in% | |
| c("both", "column"))) { | |
| if (is.logical(Rowv) && (Rowv)) | |
| dendrogram <- "row" | |
| else dendrogram <- "none" | |
| warning("Discrepancy: Colv is FALSE, while dendrogram is `", | |
| dendrogram, "'. Omitting column dendogram.") | |
| } | |
| } | |
| if (inherits(Rowv, "dendrogram")) { | |
| ddr <- Rowv | |
| rowInd <- order.dendrogram(ddr) | |
| } | |
| else if (is.integer(Rowv)) { | |
| hcr <- hclustfun(distfun(x)) | |
| ddr <- as.dendrogram(hcr) | |
| ddr <- reorder(ddr, Rowv) | |
| rowInd <- order.dendrogram(ddr) | |
| if (nr != length(rowInd)) | |
| stop("row dendrogram ordering gave index of wrong length") | |
| } | |
| else if (isTRUE(Rowv)) { | |
| Rowv <- rowMeans(x, na.rm = na.rm) | |
| hcr <- hclustfun(distfun(x)) | |
| ddr <- as.dendrogram(hcr) | |
| ddr <- reorder(ddr, Rowv) | |
| rowInd <- order.dendrogram(ddr) | |
| if (nr != length(rowInd)) | |
| stop("row dendrogram ordering gave index of wrong length") | |
| } | |
| else { | |
| rowInd <- nr:1 | |
| } | |
| if (inherits(Colv, "dendrogram")) { | |
| ddc <- Colv | |
| colInd <- order.dendrogram(ddc) | |
| } | |
| else if (identical(Colv, "Rowv")) { | |
| if (nr != nc) | |
| stop("Colv = \"Rowv\" but nrow(x) != ncol(x)") | |
| if (exists("ddr")) { | |
| ddc <- ddr | |
| colInd <- order.dendrogram(ddc) | |
| } | |
| else colInd <- rowInd | |
| } | |
| else if (is.integer(Colv)) { | |
| hcc <- hclustfun(distfun(if (symm) | |
| x | |
| else t(x))) | |
| ddc <- as.dendrogram(hcc) | |
| ddc <- reorder(ddc, Colv) | |
| colInd <- order.dendrogram(ddc) | |
| if (nc != length(colInd)) | |
| stop("column dendrogram ordering gave index of wrong length") | |
| } | |
| else if (isTRUE(Colv)) { | |
| Colv <- colMeans(x, na.rm = na.rm) | |
| hcc <- hclustfun(distfun(if (symm) | |
| x | |
| else t(x))) | |
| ddc <- as.dendrogram(hcc) | |
| ddc <- reorder(ddc, Colv) | |
| colInd <- order.dendrogram(ddc) | |
| if (nc != length(colInd)) | |
| stop("column dendrogram ordering gave index of wrong length") | |
| } | |
| else { | |
| colInd <- 1:nc | |
| } | |
| retval$rowInd <- rowInd | |
| retval$colInd <- colInd | |
| retval$call <- match.call() | |
| x <- x[rowInd, colInd] | |
| x.unscaled <- x | |
| cellnote <- cellnote[rowInd, colInd] | |
| if (is.null(labRow)) | |
| labRow <- if (is.null(rownames(x))) | |
| (1:nr)[rowInd] | |
| else rownames(x) | |
| else labRow <- labRow[rowInd] | |
| if (is.null(labCol)) | |
| labCol <- if (is.null(colnames(x))) | |
| (1:nc)[colInd] | |
| else colnames(x) | |
| else labCol <- labCol[colInd] | |
| if (scale == "row") { | |
| retval$rowMeans <- rm <- rowMeans(x, na.rm = na.rm) | |
| x <- sweep(x, 1, rm) | |
| retval$rowSDs <- sx <- apply(x, 1, sd, na.rm = na.rm) | |
| x <- sweep(x, 1, sx, "/") | |
| } | |
| else if (scale == "column") { | |
| retval$colMeans <- rm <- colMeans(x, na.rm = na.rm) | |
| x <- sweep(x, 2, rm) | |
| retval$colSDs <- sx <- apply(x, 2, sd, na.rm = na.rm) | |
| x <- sweep(x, 2, sx, "/") | |
| } | |
| if (missing(breaks) || is.null(breaks) || length(breaks) < 1) { | |
| if (missing(col) || is.function(col)) | |
| breaks <- 16 | |
| else breaks <- length(col) + 1 | |
| } | |
| if (length(breaks) == 1) { | |
| if (!symbreaks) | |
| breaks <- seq(min(x, na.rm = na.rm), max(x, na.rm = na.rm), | |
| length = breaks) | |
| else { | |
| extreme <- max(abs(x), na.rm = TRUE) | |
| breaks <- seq(-extreme, extreme, length = breaks) | |
| } | |
| } | |
| nbr <- length(breaks) | |
| ncol <- length(breaks) - 1 | |
| if (class(col) == "function") | |
| col <- col(ncol) | |
| min.breaks <- min(breaks) | |
| max.breaks <- max(breaks) | |
| x[x < min.breaks] <- min.breaks | |
| x[x > max.breaks] <- max.breaks | |
| if (missing(lhei) || is.null(lhei)) | |
| lhei <- c(keysize, 4) | |
| if (missing(lwid) || is.null(lwid)) | |
| lwid <- c(keysize, 4) | |
| if (missing(lmat) || is.null(lmat)) { | |
| lmat <- rbind(4:3, 2:1) | |
| if (!missing(ColSideColors)) { | |
| #if (!is.matrix(ColSideColors)) | |
| #stop("'ColSideColors' must be a matrix") | |
| if (!is.character(ColSideColors) || nrow(ColSideColors) != nc) | |
| stop("'ColSideColors' must be a matrix of nrow(x) rows") | |
| lmat <- rbind(lmat[1, ] + 1, c(NA, 1), lmat[2, ] + 1) | |
| #lhei <- c(lhei[1], 0.2, lhei[2]) | |
| lhei=c(lhei[1], side.height.fraction*NumColSideColors, lhei[2]) | |
| } | |
| if (!missing(RowSideColors)) { | |
| #if (!is.matrix(RowSideColors)) | |
| #stop("'RowSideColors' must be a matrix") | |
| if (!is.character(RowSideColors) || ncol(RowSideColors) != nr) | |
| stop("'RowSideColors' must be a matrix of ncol(x) columns") | |
| lmat <- cbind(lmat[, 1] + 1, c(rep(NA, nrow(lmat) - 1), 1), lmat[,2] + 1) | |
| #lwid <- c(lwid[1], 0.2, lwid[2]) | |
| lwid <- c(lwid[1], side.height.fraction*NumRowSideColors, lwid[2]) | |
| } | |
| lmat[is.na(lmat)] <- 0 | |
| } | |
| if (length(lhei) != nrow(lmat)) | |
| stop("lhei must have length = nrow(lmat) = ", nrow(lmat)) | |
| if (length(lwid) != ncol(lmat)) | |
| stop("lwid must have length = ncol(lmat) =", ncol(lmat)) | |
| op <- par(no.readonly = TRUE) | |
| on.exit(par(op)) | |
| layout(lmat, widths = lwid, heights = lhei, respect = FALSE) | |
| if (!missing(RowSideColors)) { | |
| if (!is.matrix(RowSideColors)){ | |
| par(mar = c(margins[1], 0, 0, 0.5)) | |
| image(rbind(1:nr), col = RowSideColors[rowInd], axes = FALSE) | |
| } else { | |
| par(mar = c(margins[1], 0, 0, 0.5)) | |
| rsc = t(RowSideColors[,rowInd, drop=F]) | |
| rsc.colors = matrix() | |
| rsc.names = names(table(rsc)) | |
| rsc.i = 1 | |
| for (rsc.name in rsc.names) { | |
| rsc.colors[rsc.i] = rsc.name | |
| rsc[rsc == rsc.name] = rsc.i | |
| rsc.i = rsc.i + 1 | |
| } | |
| rsc = matrix(as.numeric(rsc), nrow = dim(rsc)[1]) | |
| image(t(rsc), col = as.vector(rsc.colors), axes = FALSE) | |
| if (length(colnames(RowSideColors)) > 0) { | |
| axis(1, 0:(dim(rsc)[2] - 1)/(dim(rsc)[2] - 1), colnames(RowSideColors), las = 2, tick = FALSE) | |
| } | |
| } | |
| } | |
| if (!missing(ColSideColors)) { | |
| if (!is.matrix(ColSideColors)){ | |
| par(mar = c(0.5, 0, 0, margins[2])) | |
| image(cbind(1:nc), col = ColSideColors[colInd], axes = FALSE) | |
| } else { | |
| par(mar = c(0.5, 0, 0, margins[2])) | |
| csc = ColSideColors[colInd, , drop=F] | |
| csc.colors = matrix() | |
| csc.names = names(table(csc)) | |
| csc.i = 1 | |
| for (csc.name in csc.names) { | |
| csc.colors[csc.i] = csc.name | |
| csc[csc == csc.name] = csc.i | |
| csc.i = csc.i + 1 | |
| } | |
| csc = matrix(as.numeric(csc), nrow = dim(csc)[1]) | |
| image(csc, col = as.vector(csc.colors), axes = FALSE) | |
| if (length(colnames(ColSideColors)) > 0) { | |
| axis(2, 0:(dim(csc)[2] - 1)/max(1,(dim(csc)[2] - 1)), colnames(ColSideColors), las = 2, tick = FALSE) | |
| } | |
| } | |
| } | |
| par(mar = c(margins[1], 0, 0, margins[2])) | |
| x <- t(x) | |
| cellnote <- t(cellnote) | |
| if (revC) { | |
| iy <- nr:1 | |
| if (exists("ddr")) | |
| ddr <- rev(ddr) | |
| x <- x[, iy] | |
| cellnote <- cellnote[, iy] | |
| } | |
| else iy <- 1:nr | |
| image(1:nc, 1:nr, x, xlim = 0.5 + c(0, nc), ylim = 0.5 + c(0, nr), axes = FALSE, xlab = "", ylab = "", col = col, breaks = breaks, ...) | |
| retval$carpet <- x | |
| if (exists("ddr")) | |
| retval$rowDendrogram <- ddr | |
| if (exists("ddc")) | |
| retval$colDendrogram <- ddc | |
| retval$breaks <- breaks | |
| retval$col <- col | |
| if (!invalid(na.color) & any(is.na(x))) { # load library(gplots) | |
| mmat <- ifelse(is.na(x), 1, NA) | |
| image(1:nc, 1:nr, mmat, axes = FALSE, xlab = "", ylab = "", | |
| col = na.color, add = TRUE) | |
| } | |
| axis(1, 1:nc, labels = labCol, las = 2, line = -0.5, tick = 0, | |
| cex.axis = cexCol) | |
| if (!is.null(xlab)) | |
| mtext(xlab, side = 1, line = margins[1] - 1.25) | |
| axis(4, iy, labels = labRow, las = 2, line = -0.5, tick = 0, | |
| cex.axis = cexRow) | |
| if (!is.null(ylab)) | |
| mtext(ylab, side = 4, line = margins[2] - 1.25) | |
| if (!missing(add.expr)) | |
| eval(substitute(add.expr)) | |
| if (!missing(colsep)) | |
| for (csep in colsep) rect(xleft = csep + 0.5, ybottom = rep(0, length(csep)), xright = csep + 0.5 + sepwidth[1], ytop = rep(ncol(x) + 1, csep), lty = 1, lwd = 1, col = sepcolor, border = sepcolor) | |
| if (!missing(rowsep)) | |
| for (rsep in rowsep) rect(xleft = 0, ybottom = (ncol(x) + 1 - rsep) - 0.5, xright = nrow(x) + 1, ytop = (ncol(x) + 1 - rsep) - 0.5 - sepwidth[2], lty = 1, lwd = 1, col = sepcolor, border = sepcolor) | |
| min.scale <- min(breaks) | |
| max.scale <- max(breaks) | |
| x.scaled <- scale01(t(x), min.scale, max.scale) | |
| if (trace %in% c("both", "column")) { | |
| retval$vline <- vline | |
| vline.vals <- scale01(vline, min.scale, max.scale) | |
| for (i in colInd) { | |
| if (!is.null(vline)) { | |
| abline(v = i - 0.5 + vline.vals, col = linecol, | |
| lty = 2) | |
| } | |
| xv <- rep(i, nrow(x.scaled)) + x.scaled[, i] - 0.5 | |
| xv <- c(xv[1], xv) | |
| yv <- 1:length(xv) - 0.5 | |
| lines(x = xv, y = yv, lwd = 1, col = tracecol, type = "s") | |
| } | |
| } | |
| if (trace %in% c("both", "row")) { | |
| retval$hline <- hline | |
| hline.vals <- scale01(hline, min.scale, max.scale) | |
| for (i in rowInd) { | |
| if (!is.null(hline)) { | |
| abline(h = i + hline, col = linecol, lty = 2) | |
| } | |
| yv <- rep(i, ncol(x.scaled)) + x.scaled[i, ] - 0.5 | |
| yv <- rev(c(yv[1], yv)) | |
| xv <- length(yv):1 - 0.5 | |
| lines(x = xv, y = yv, lwd = 1, col = tracecol, type = "s") | |
| } | |
| } | |
| if (!missing(cellnote)) | |
| text(x = c(row(cellnote)), y = c(col(cellnote)), labels = c(cellnote), | |
| col = notecol, cex = notecex) | |
| par(mar = c(margins[1], 0, 0, 0)) | |
| if (dendrogram %in% c("both", "row")) { | |
| plot(ddr, horiz = TRUE, axes = FALSE, yaxs = "i", leaflab = "none") | |
| } | |
| else plot.new() | |
| par(mar = c(0, 0, if (!is.null(main)) 5 else 0, margins[2])) | |
| if (dendrogram %in% c("both", "column")) { | |
| plot(ddc, axes = FALSE, xaxs = "i", leaflab = "none") | |
| } | |
| else plot.new() | |
| if (!is.null(main)) | |
| title(main, cex.main = 1.5 * op[["cex.main"]]) | |
| if (key) { | |
| par(mar = c(5, 4, 2, 1), cex = 0.75) | |
| tmpbreaks <- breaks | |
| if (symkey) { | |
| max.raw <- max(abs(c(x, breaks)), na.rm = TRUE) | |
| min.raw <- -max.raw | |
| tmpbreaks[1] <- -max(abs(x), na.rm = TRUE) | |
| tmpbreaks[length(tmpbreaks)] <- max(abs(x), na.rm = TRUE) | |
| } | |
| else { | |
| min.raw <- min(x, na.rm = TRUE) | |
| max.raw <- max(x, na.rm = TRUE) | |
| } | |
| z <- seq(min.raw, max.raw, length = length(col)) | |
| image(z = matrix(z, ncol = 1), col = col, breaks = tmpbreaks, | |
| xaxt = "n", yaxt = "n") | |
| par(usr = c(0, 1, 0, 1)) | |
| lv <- pretty(breaks) | |
| xv <- scale01(as.numeric(lv), min.raw, max.raw) | |
| axis(1, at = xv, labels = lv) | |
| if (scale == "row") | |
| mtext(side = 1, "Row Z-Score", line = 2) | |
| else if (scale == "column") | |
| mtext(side = 1, "Column Z-Score", line = 2) | |
| else mtext(side = 1, KeyValueName, line = 2) | |
| if (density.info == "density") { | |
| dens <- density(x, adjust = densadj, na.rm = TRUE) | |
| omit <- dens$x < min(breaks) | dens$x > max(breaks) | |
| dens$x <- dens$x[-omit] | |
| dens$y <- dens$y[-omit] | |
| dens$x <- scale01(dens$x, min.raw, max.raw) | |
| lines(dens$x, dens$y/max(dens$y) * 0.95, col = denscol, | |
| lwd = 1) | |
| axis(2, at = pretty(dens$y)/max(dens$y) * 0.95, pretty(dens$y)) | |
| title("Color Key\nand Density Plot") | |
| par(cex = 0.5) | |
| mtext(side = 2, "Density", line = 2) | |
| } | |
| else if (density.info == "histogram") { | |
| h <- hist(x, plot = FALSE, breaks = breaks) | |
| hx <- scale01(breaks, min.raw, max.raw) | |
| hy <- c(h$counts, h$counts[length(h$counts)]) | |
| lines(hx, hy/max(hy) * 0.95, lwd = 1, type = "s", | |
| col = denscol) | |
| axis(2, at = pretty(hy)/max(hy) * 0.95, pretty(hy)) | |
| title("Color Key\nand Histogram") | |
| par(cex = 0.5) | |
| mtext(side = 2, "Count", line = 2) | |
| } | |
| else title("Color Key") | |
| } | |
| else plot.new() | |
| retval$colorTable <- data.frame(low = retval$breaks[-length(retval$breaks)], | |
| high = retval$breaks[-1], color = retval$col) | |
| invisible(retval) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment