[R] Avoiding loops to spare time and memory

Ernesto Jardim ernesto at ipimar.pt
Thu May 8 11:45:48 CEST 2003

```On Thu, 2003-05-08 at 10:31, Dirk Enzmann wrote:
> I create vectors of eigenvalues of correlation matrices of random numbers for x items and y cases  i-1-times and
> add them via rbind to the already calculated eigenvalues. Thus, at the end of the loop I have a matrix of
> items*samples eigenvalues.
>
> Ernesto Jardim schrieb:
>
> > On Thu, 2003-05-08 at 09:58, Dirk Enzmann wrote:
> > > Is it possible to avoid the loop in the following function (or make the
> > > function otherwise more efficient) and can someone point me to a
> > > possible solution? (It would be great if hours could be reduced to
> > > seconds :-).
> > >
> > > # ---------------------------------------------
> > > RanEigen=function(items=x,cases=y,sample=z)
> > > {
> > >   X=matrix(rnorm(cases*items),nrow=cases,byrow=F)
> > >   S=crossprod(X-rep(1,cases) %*% t(colMeans(X)))
> > >
> > > EV=eigen((1/sqrt(diag(S))*diag(items))%*%S%*%(1/sqrt(diag(S))*diag(items)),only.values=T)\$values
> > >
> > >   for (i in 2:sample)
> > >   {
> > >   X=matrix(rnorm(cases*items),nrow=cases,byrow=F)
> > >   S=crossprod(X-rep(1,cases) %*% t(colMeans(X)))
> > >
> > > EV=rbind(EV,eigen((1/sqrt(diag(S))*diag(items))%*%S%*%(1/sqrt(diag(S))*diag(items)),only.values=T)\$values)
> > >
> > >   }
> > >   REigV=(cbind(1:items,colMeans(EV)))
> > >   REigV[,2]=as.numeric(formatC(REigV[,2],format="f",digits=7,flag="
> > > ",width=10))
> > >   colnames(REigV)=c(' ','Eigenvalue')
> > >   rownames(REigV)=rep('',items)
> > >   return(REigV)
> > > }
> > > # ---------------------------------------------
> > >
> > > Thanks in advance,
> > > Dirk
> > >
> > >
> > > *************************************************
> > > Dr. Dirk Enzmann
> > > Criminological Research Institute of Lower Saxony
> > > Luetzerodestr. 9
> > > D-30161 Hannover
> > > Germany
> > >
> > > phone: +49-511-348.36.32
> > > fax:   +49-511-348.36.10
> > > email: ENZMANN at KFN.uni-hannover.de
> > >
> > > http://www.kfn.de
> > >
> > > ______________________________________________
> > > R-help at stat.math.ethz.ch mailing list
> > > https://www.stat.math.ethz.ch/mailman/listinfo/r-help
> >
> > Hi
> >
> > You're not using the value of i inside your loop. Why do you need the
> > loop ?
> >
> > EJ
>
> --
> *************************************************
> Dr. Dirk Enzmann
> Criminological Research Institute of Lower Saxony
> Luetzerodestr. 9
> D-30161 Hannover
> Germany
>
> phone: +49-511-348.36.32
> fax:   +49-511-348.36.10
> email: ENZMANN at KFN.uni-hannover.de
>
> http://www.kfn.de
> *************************************************
>

To avoid the loop you can try someting like :

fun <- function(){
X=matrix(rnorm(cases*items),nrow=cases,byrow=F)
S=crossprod(X-rep(1,cases) %*% t(colMeans(X)))
EV=rbind(EV,eigen((1/sqrt(diag(S))*diag(items))%*%S%*%(1/sqrt(diag(S))*diag(items)),only.values=T)\$values)
}

lst1 <- split(c(2:sample),c(2:sample))
lst2 <- lapply(lst1,fun)

This is not the most elegant way of doing it, but it worked for me. The
idea is to create a list with the number of samples you want and then
use "lapply" that is much faster then loop.

In the end you get a list with the results. You can use "unlist" to
change it into a vector.

Hope it helps

Regards

EJ

```