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

From: Charles C. Berry <cberry_at_tajo.ucsd.edu>
Date: Wed 24 Jan 2007 - 01:39:00 GMT

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@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@tajo.ucsd.edu UC San Diego
> http://biostat.ucsd.edu/~cberry/ La Jolla, San Diego 92093-0901
>
> ______________________________________________
> R-help@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@tajo.ucsd.edu	         UC San Diego
http://biostat.ucsd.edu/~cberry/         La Jolla, San Diego 92093-0901

______________________________________________
```
R-help@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. Received on Wed Jan 24 12:43:50 2007

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Wed 24 Jan 2007 - 04:30:33 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.