[R] [fixed] vectorized nested loop: apply a function that takes two rows
Jose Quesada
quesada at gmail.com
Tue Jan 23 21:46:27 CET 2007
(Extremely sorry, disregard previous email as I hit send before pasting the latest version of the example; this one is smaller too)
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(100), 10, 10)
# this is actually a very large sparse matrix, but it doesn't matter for the
# example
library(Matrix)
x = as(x,"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)))
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?
Also, I have noticed that getting a row from a Matrix object produces a normal
array (i.e., it does not inherit Matrix class). However, selecting >1 rows, does
produce a same-class matrix. If I convert with as() the output of selecting one
row, am I losing performance? Is there any way to make the resulting vector be a
1-D Matrix object?
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
More information about the R-help
mailing list