# [R] [fixed] vectorized nested loop: apply a function that takes two rows

Charles C. Berry cberry at tajo.ucsd.edu
Wed Jan 24 02:39:00 CET 2007

```On Tue, 23 Jan 2007, Charles C. Berry wrote:

>
>
> 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 ) )
>

OOPS! Better make that

diagnl <- Diagonal( ncol(x), 1 / 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?
>> --
>> -Jose
>>
>> --
>> Research fellow, Psychology Dept.
>> Sussex University, Brighton, UK
>>
>> ______________________________________________
>> R-help at stat.math.ethz.ch mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> 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
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help