#' Function for biplotting with no point labels and with #' points color-coded according to a quantitative variable. #' For example: the rank of normalization performance. #' #' This function implements biplot for \code{\link[stats]{prcomp}} objects. #' #' @param x \code{\link[stats]{prcomp}} object. #' @param y numeric. Quantitative values used to color the points. If rank is #' FALSE, all values must be positive integers and less than or equal to the #' length of y. #' @param rank logical. If TRUE (default) y will be transformed by the rank() #' function #' @param ties_method character. ties.method used by the rank() function #' @param choices numeric. 2 principal components to plot. Default to first two #' PCs. #' @param expand numeric. value used to adjust the spread of the arrows #' relative to the points. #' @param ... arguments passed to plot. #' #' @importFrom grDevices colorRampPalette #' @export #' #' @return Invisibly returns scaled point coordinates used in plot. #' #' @examples #' mat <- matrix(rnorm(1000), ncol=10) #' colnames(mat) <- paste("X", 1:ncol(mat), sep="") #' #' pc <- prcomp(mat) #' #' biplot_color(pc, rank(pc$x[,1])) #' biplot_color <- function(x, y, rank = TRUE, ties_method = c("max", "min", "first", "last", "random"), choices = 1:2, expand = 1, ...) { if(rank){ ties_method <- match.arg(ties_method) y = rank(y,ties.method = ties_method) }else{ if(any(abs(y - round(y)) > .Machine$double.eps^0.5)){ stop("ranks must be integer") }else{y = as.integer(y)} if(any(y <= 0)){ stop("ranks must be positive") } if(any(y > length(y))){ stop("ranks must be less than or equal to total number of elements") } } lam <- x$sdev[choices] n <- NROW(x$x) lam <- lam * sqrt(n) xx <- t(t(x$x[, choices])/lam) yy <- t(t(x$rotation[, choices]) * lam) ratio <- max(range(yy)/range(xx))/expand cols <- rev(colorRampPalette(c("black","navyblue","mediumblue", "dodgerblue3","aquamarine4","green4", "yellowgreen","yellow"))(length(y)))[y] plot(xx, pch=19, col=cols, ...) labs <- rownames(yy) text(yy/ratio, labels=labs, col=2) arrows(0, 0, yy[, 1] * 0.8/ratio, yy[, 2] * 0.8/ratio, col = 2, length = 0.1) invisible(xx) }