s-news
[Top] [All Lists]

Summary of replies on: Operations on pair of matrices, avoiding l oops

To: "'s-news@lists.biostat.wustl.edu'" <s-news@lists.biostat.wustl.edu>
Subject: Summary of replies on: Operations on pair of matrices, avoiding l oops
From: Marco Bianchi <M.Bianchi@nrcl.com>
Date: Tue, 20 May 2003 14:26:03 +0100
Summary Response: Operations on pair of matrices,
avoiding loops.

Thank you to Tony, Vumani, Dimistris and Spencer
who have all given valid solutions to my problem.
I have tried all their solutions
(avoiding loops) plus the loop one described in
my email.

In all 5 cases, I got the same identical results
and the time to perform the operations was
identical too. I was perhaps somewhat surprised
of the fact that the 1 loop option took exactly
the same run time of the remaining 4 non loop
options, but that was it.

Marco Bianchi


===================================================
MY ORIGINAL MESSAGE

Dear Splus users

I am trying to perform some calculations in S-plus avoiding loops.

Here is my problem. I have a 2-argument function called myFunc(x,y)

where x and y are column vectors of equal length nr. 
The myFunc function takes the two vectors and performs some more or less
complicated operations on them to return
the final desired result.

The myFunc function, I wish to apply to a PAIR of matrices, columnwise.
Say I have 2 matrices X and Y (note uppercase here as opposed to lower case
vector notation before),
both of order nr x nc, where nr is the number of rows as above and nc is the
number of columns.

Obviously, I can solve my problem looping in the following way
result <- rep(NA, nc)
for(i in 1:nc){
   x <- X[,i]
   y <- Y[,i]  
   result[i] <- myFunc(x,y)
   }

I am looking, however, to avoid the loop. I would appreciate any help from
other Splus users who may have previously encountered a similar problem or
have a solution to this.


Many thanks
Marco Bianchi
London

===================================================

TONY PLATE
If I understand you correctly, you can do what you want to by constructing 
a 3-d matrix (as you did in the last part of your message).

 > set.seed(1)
 > x <- matrix(sample(12,12),nrow=3)
 > y <- matrix(sample(12,12),nrow=3)
 > xy <- array(c(x,y), dim=c(3,4,2))
 > xy

, , 1
      [,1] [,2] [,3] [,4]
[1,]    6    7    2   12
[2,]    5   10    9   11
[3,]    1    3    4    8

, , 2
      [,1] [,2] [,3] [,4]
[1,]    1    7    4   10
[2,]   12   11    6    3
[3,]    5    9    8    2
 > dim(xy)
[1] 3 4 2
 > # apply the cor() function to pairs of rows from x and y
 > apply(xy, 1, function(m) cor(m[,1],m[,2]))
[1]  0.7219295 -0.6871031 -0.5728919
 > # verify this gave us the intended results
 > cor(x[1,], y[1,])
[1] 0.7219295
 > cor(x[2,], y[2,])
[1] -0.6871031
 > cor(x[3,], y[3,])
[1] -0.5728919
 > # not restricted to the function returning a scalar value
 > apply(xy, 1, function(m) c(dim(m), cor(m[,1],m[,2])))
           [,1]       [,2]       [,3]
[1,] 4.0000000  4.0000000  4.0000000
[2,] 2.0000000  2.0000000  2.0000000
[3,] 0.7219295 -0.6871031 -0.5728919
 > # a more general (and easier) way to construct 3-d arrays (and other-d 
arrays) is to use the abind() function from statlib, e.g.:
 > xy1 <- abind(x,y,along=3)
 > all(xy1==xy)
[1] T
 >

cheers,

Tony Plate

=====================================================

VUMANI
This might do the trick:

result<-lapply(1:nc,function(i) {x<-X[,i];y<-Y[,i];myFunc(x,y)})

If "myFunc" returns a scalar you can simply unlist the above expression.

Vumani

=====================================================
DIMISTRIS

Dear Marco,

you could use a combination of apply and for, which sometimes performs
very well!!

In your case it should be something like this:

out <- apply(X, 2, function(x, Y, nc){
res <- numeric(nc)
for(i in 1:nc) res[i] <- myFunc(x,Y[,i])
}, Y, nc)

I hope this helps.

Best,
Dimitris
=====================================================

SPENCER

          The obvious generalization of the following should do what I 
understood you to ask:

        tst <- array(1:4, dim=c(2,2))
        sapply(1:2, function(x, mat)(mat[,x]+mat[,x]), mat=tst)

          Why do you want to avoid the "for" loop?  It is my understanding
that 
for small "nc", a "for" loop is one of the best tools for accomplishing 
what you wrote, especially with the improvements in S-Plus 6.

hope this helps.  spencer graves


<Prev in Thread] Current Thread [Next in Thread>
  • Summary of replies on: Operations on pair of matrices, avoiding l oops, Marco Bianchi <=