Jose Quesada
2007-Jan-23 20:40 UTC
[R] vectorized nested loop: apply a function that takes two rows
Dear R users, I want to apply a function that takes two vectors as input to all pairs (combinations (nrow(X), 2))of matrix rows in a matrix. I know that ideally, one should avoid loops in R, but after reading the docs for do.call, apply, etc, I still don't know how to write the nested loop in a vectorized way. Example data: x = matrix(rnorm(1000), 100, 100) zeros = runif(90) x[] # this is actually a very large sparse matrix, but it doesn't matter for the # example library(Matrix) x = as(dat,"CsparseMatrix") # cosine function cosine = function (x, y){ if (is.vector(x) && is.vector(y)) { return(crossprod(x, y)/sqrt(crossprod(x) * crossprod(y))) } else {stop("cosine: argument mismatch. Two vectors needed as input.")} } # The loop-based solution I have is: if (is(x, "Matrix") ) { cos = array(NA, c(ncol(x), ncol(x))) # preallocate memory for (i in 2:ncol(x)) { for (j in 1:(i - 1)) { cos[i, j] = cosine(x[, i], x[, j]) } } } This solution seems inneficient. Is there an easy way of achieving this with a clever do.call + apply combination? -- Thanks in advance, -Jose -- Jose Quesada, PhD Research fellow, Psychology Dept. Sussex University, Brighton, UK http://www.andrew.cmu.edu/~jquesada