[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