Adaikalavan Ramasamy <ramasamy <at> cancer.org.uk> writes: : : There was a BioConductor thread today where the poster wanted to find : pairwise difference between columns of a matrix. I suggested the slow : solution below, hoping that someone might suggest a faster and/or more : elegant solution, but no other response. : : I tried unsuccessfully with the apply() family. Searching the mailing : list was not very fruitful either. The closest I got to was a cryptic : chunk of code in pairwise.table(). : : Since I do use something similar myself occasionally, I am hoping : someone from the R-help list can suggest alternatives or past threads. : Thank you. : : ### Code ### : pairwise.difference <- function(m){ : npairs <- choose( ncol(m), 2 ) : results <- matrix( NA, nc=npairs, nr=nrow(m) ) : cnames <- rep(NA, npairs) : if(is.null(colnames(m))) colnames(m) <- paste("col", 1:ncol(m), sep="") : : k <- 1 : for(i in 1:ncol(m)){ : for(j in 1:ncol(m)){ : if(j <= i) next; : results[ ,k] <- m[ ,i] - m[ ,j] : cnames[k] <- paste(colnames(m)[ c(i, j) ], collapse=".vs.") : k <- k + 1 : } : } : : colnames(results) <- cnames : rownames(results) <- rownames(m) : return(results) : } : : ### Example using a matrix with 5 gene/row and 4 columns ### : mat <- matrix( sample(1:20), nc=4 ) : colnames(mat) <- LETTERS[1:4]; rownames(mat) <- paste( "g", 1:5, sep="") : mat : A B C D : g1 10 16 3 15 : g2 18 5 12 19 : g3 7 4 8 13 : g4 14 2 6 11 : g5 17 1 20 9 : : pairwise.difference(mat) : A.vs.B A.vs.C A.vs.D B.vs.C B.vs.D C.vs.D : g1 -6 7 -5 13 1 -12 : g2 13 6 -1 -7 -14 -7 : g3 3 -1 -6 -4 -9 -5 : g4 12 8 3 -4 -9 -5 : g5 16 -3 8 -19 -8 11
1. Note that mat[,j] - mat subtracts each column of mat from the j-th column so we just cbind 3 matrices: cbind( mat[,1]-mat[2:4], mat[,2]-mat[,3:4], mat[,3]-mat[,4,drop=F] ) 2. For a general matrix a single sapply can do it like this: f <- function(i, mat) mat[, i-1] - mat[, i:ncol(mat), drop = FALSE] do.call("cbind", sapply(2:ncol(mat), f, mat)) 3. To add nice column names just enhance f. The statements "z <- ..." and "do.call ..." are the same as before: f <- function(i, mat) { z <- mat[, i-1] - mat[, i:ncol(mat), drop = FALSE] colnames(z) <- paste(colnames(mat)[i-1], colnames(z), sep = "-") z } do.call("cbind", sapply(2:ncol(mat), f, mat)) ______________________________________________ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html