| # File src/library/stats/R/cancor.R |
| # Part of the R package, https://www.R-project.org |
| # |
| # Copyright (C) 1995-2012 The R Core Team |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 2 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # A copy of the GNU General Public License is available at |
| # https://www.R-project.org/Licenses/ |
| |
| ## Seber pages 506-507, after a Golub original |
| |
| cancor <- function(x, y, xcenter=TRUE, ycenter=TRUE) |
| { |
| x <- as.matrix(x) |
| y <- as.matrix(y) |
| if((nr <- nrow(x)) != nrow(y)) stop("unequal number of rows in 'cancor'") |
| ncx <- ncol(x) |
| ncy <- ncol(y) |
| if(!nr || !ncx || !ncy) stop("dimension 0 in 'x' or 'y'") |
| if(is.logical(xcenter)) { |
| if(xcenter) { |
| xcenter <- colMeans(x,) |
| x <- x - rep(xcenter, rep.int(nr, ncx)) |
| } |
| else xcenter <- rep.int(0, ncx) |
| } |
| else { |
| xcenter <- rep_len(xcenter, ncx) |
| x <- x - rep(xcenter, rep.int(nr, ncx)) |
| } |
| if(is.logical(ycenter)) { |
| if(ycenter) { |
| ycenter <- colMeans(y) |
| y <- y - rep(ycenter, rep.int(nr, ncy)) |
| } |
| else ycenter <- rep.int(0, ncy) |
| } |
| else { |
| ycenter <- rep_len(ycenter, ncy) |
| y <- y - rep(ycenter, rep.int(nr, ncy)) |
| } |
| qx <- qr(x) |
| qy <- qr(y) |
| dx <- qx$rank; if(!dx) stop("'x' has rank 0") |
| dy <- qy$rank; if(!dy) stop("'y' has rank 0") |
| ## compute svd(Qx'Qy) |
| z <- svd(qr.qty(qx, qr.qy(qy, diag(1, nr, dy)))[1L:dx,, drop = FALSE], |
| dx, dy) |
| xcoef <- backsolve((qx$qr)[1L:dx, 1L:dx, drop = FALSE], z$u) |
| rownames(xcoef) <- colnames(x)[qx$pivot][1L:dx] |
| ycoef <- backsolve((qy$qr)[1L:dy, 1L:dy, drop = FALSE], z$v) |
| rownames(ycoef) <- colnames(y)[qy$pivot][1L:dy] |
| list(cor = z$d, xcoef = xcoef, ycoef = ycoef, xcenter = xcenter, |
| ycenter = ycenter) |
| } |