[R] how to speed up this for loop?

Nordlund, Dan (DSHS/RDA) NordlDJ at dshs.wa.gov
Tue Jul 22 19:30:47 CEST 2008


> -----Original Message-----
> From: r-help-bounces at r-project.org 
> [mailto:r-help-bounces at r-project.org] On Behalf Of Rheannon
> Sent: Tuesday, July 22, 2008 9:09 AM
> To: r-help at r-project.org
> Subject: Re: [R] how to speed up this for loop?
> 
> 
> Here is the full code:
> 
> R <- 5328
> #Temp is a temperature file with daily temp. values for each 
> day of the
> year, for 5328 locations
> Temp <- rnorm(100)
> dim(Temp) <- c(365,5328)
> # transpose temp dataframe in order to perform rollmean 
> (running mean) on
> proper data section
> Temp_T <- t(Temp)
> library(zoo)
> Temp_T <- zoo(Temp_T)
> 
> #**** 31 DAY RUNNING MEAN *********
> RM <- rollmean(Temp_T, 31)
> 
> #function that finds first negative number, if there are none 
> a value of 365
> will be output
> firstneg = function(x)if(any(x<0))min(which(x<0)) else 335
> 
> #apply the function to every column in Matrix
> FN <- apply(RM,2,firstneg)
> 
> #problem: column values are off by 30 (31 day running mean)
> FN <- matrix(FN) 
> add = function(x)x=x+30
> FN <- apply(FN,2,add)
> 
> #function that finds last negative number, if there are none 
> a value of 365
> will be output
> lastneg = function(x)if(any(x<0))max(which(x<0)) else 335
> 
> #apply the function to every column in Matrix
> LN <- apply(RM,2,lastneg)
> 
> #problem: column values are off by 30
> LN <- matrix(LN) 
> LN <- apply(LN,2,add)
> RMT <- t(RM)
> 
> #Create and fill an empty matrix with zeros
> sum <- matrix(nrow=R,ncol=1)
> for(i in 1:R){sum[i] <- 0}
> 
> #******This is the loop that I would like to speed up************
> 
> #sum values between FN and LN, excluding positive values
> for(i in 1:R){
> for(j in FN[i]:LN[i]){
> if(Temp[i,j]<0)
> sum[i] <- sum[i] + sum(Temp[i,j])}}
> 

Using sum for a matrix name was very confusing to my eyes trying to differentiate square brackets from parentheses.  You may have even confused yourself.  However, does this get you close to what you want?

#sum values between FN and LN, excluding positive values
for(i in 1:R){
  sum[i] <- sum(Temp[i,Temp[I,FN[i]:LN[i]]>0]) }
 
Hope this helpful,

Dan

Daniel J. Nordlund
Washington State Department of Social and Health Services
Planning, Performance, and Accountability
Research and Data Analysis Division
Olympia, WA  98504-5204
 
 



More information about the R-help mailing list