e.moran
e.moran

Reputation: 49

avoid nested for-loops for tricky operation R

I have to do an operation that involves two matrices, matrix #1 with data and matrix #2 with coefficients to multiply columns of matrix #1

matrix #1 is:

dim(dat)
[1]  612 2068

dat[1:6,1:8]

  X0005 X0010 X0011 X0013 X0015 X0016 X0017 X0018
1  1.96  1.82  8.80  1.75  2.95  1.10  0.46  0.96
2  1.17  0.94  2.74  0.59  0.86  0.63  0.16  0.31
3  2.17  2.53 10.40  4.19  4.79  2.22  0.31  3.32
4  3.62  1.93  6.25  2.38  2.25  0.69  0.16  1.01
5  2.32  1.93  3.74  1.97  1.31  0.44  0.28  0.98
6  1.30  2.04  1.47  1.80  0.43  0.33  0.18  0.46

and matrix #2 is:

dim(lo)
[1] 2068    8

head(lo)

               i1         i2          i3         i4          i5          i6
X0005 -0.11858852 0.10336788  0.62618771 0.08706041 -0.02733101 0.006287923
X0010  0.06405406 0.13692216  0.64813610 0.15750302 -0.13503956 0.139280709
X0011 -0.06789727 0.30473549  0.07727417 0.24907723 -0.05345123 0.141591330
X0013  0.20909664 0.01275553  0.21067894 0.12666704 -0.02836527 0.464548147
X0015 -0.07690560 0.18788859 -0.03551084 0.19120773 -0.10196578 0.234037820
X0016 -0.06442454 0.34993481 -0.04057001 0.20258195 -0.09318325 0.130669546
              i7           i8
X0005 0.08571777  0.031531478
X0010 0.31170850 -0.003127279
X0011 0.52527759 -0.065002026
X0013 0.27858049 -0.032178156
X0015 0.50693977 -0.058003429
X0016 0.53162596 -0.052091767

I want to multiply each column of matrix#1 by its correspondent coefficient of matrix#2 first column, and sum up all resulting columns. Then repeat the operation but with coefficients of matrix#2 second column, then third column, and so on...

The result is then a matrix with 8 columns, which are lineal combinations of data in matrix#1

My attempt includes nested for-loops. it works, but takes about 30' to execute. Is there any way to avoid these loops and reduce computational effort?

here is my attempt:

r=nrow(dat)
n=ncol(dat)
m=ncol(lo)

eme<-matrix(NA,r,m)   

  for (i in(1:m)){
    SC<-matrix(NA,r,n)

    for (j in(1:n)){
     nom<-rownames(lo)
     x<-dat[ , colnames(dat) == nom[j]] 
     SC[,j]<-x*lo[j,i] 
     SC1<-rowSums(SC)
     }

    eme[,i]<-SC1
  }

Thanks for your help

Upvotes: 0

Views: 71

Answers (1)

Rorschach
Rorschach

Reputation: 32426

It looks like you are just doing matrix - vector multiplication. In R, use the%*% operator, so all the looping is delegated to a fortran routine. I think it equates to the following

apply(lo, 2, function(x) dat %*% x)

Your code could be improved by moving the nom <- assignment outside the loops since it recalculates the same thing every iteration. Also, what is the point of SC1 being computed during each iteration?

Upvotes: 0

Related Questions