[R] [fixed] vectorized nested loop: apply a function that takes two rows
Charles C. Berry
cberry at tajo.ucsd.edu
Wed Jan 24 00:20:53 CET 2007
I am rusty on 'Matrix', but I see there are crossprod methods for those
classes.
res <- crossprod( x , x )
gives your result up to scale factors of sqrt(res[i,i]*res[j,j]), so
something like
diagnl <- Diagonal( ncol(x), sqrt( diag( res ) )
final.res <- diagnl %*% res %*% diagnl
should do it.
On Tue, 23 Jan 2007, Jose Quesada wrote:
> (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
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
Charles C. Berry (858) 534-2098
Dept of Family/Preventive Medicine
E mailto:cberry at tajo.ucsd.edu UC San Diego
http://biostat.ucsd.edu/~cberry/ La Jolla, San Diego 92093-0901
More information about the R-help
mailing list