Could anyone tell me a better way to achieve the output of this for loop? It seems to run quite slow. I'm sure there must be a more consise way to sum from FN to LN, excluding positive values, for each row. #sum 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])}} Cheers, R -- View this message in context: http://www.nabble.com/how-to-speed-up-this-for-loop--tp18579577p18579577.html Sent from the R help mailing list archive at Nabble.com.
I'm not sure if I understand correct, but maybe something like: apply(dat,2,function(x) sum(x[x<0])) Please do read the posting guide and post a small, working example!!! Bart Rheannon wrote:> > Could anyone tell me a better way to achieve the output of this for loop? > It seems to run quite slow. I'm sure there must be a more consise way to > sum from FN to LN, excluding positive values, for each row. > > #sum 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])}} > > Cheers, > R >-- View this message in context: http://www.nabble.com/how-to-speed-up-this-for-loop--tp18579577p18584610.html Sent from the R help mailing list archive at Nabble.com.
Hi r-help-bounces at r-project.org napsal dne 22.07.2008 01:24:05:> > Could anyone tell me a better way to achieve the output of this forloop? It> seems to run quite slow. I'm sure there must be a more consise way tosum> from FN to LN, excluding positive values, for each row.It is difficult to understand what you really want as we do not have R, FN, LN and Temp.> vec<-rnorm(100) > sum(vec[vec<0])[1] -45.72518 Gives you sum of vec values which are lower than zero. It shall be easy to extend it to set of vectors or matrix.> mat<-rnorm(120) > dim(mat)<-c(10,12) > apply(mat, 2, function(x) sum(x[x<0]))[1] -0.9543727 -3.9965437 -6.7924017 -1.4949170 -3.8042263 -6.5552674 -2.6386912 -3.3587444 -6.3740483 -3.1178593 -7.2580333 -3.2709297 There are other options but you shall follow posting guide to obtain better answers. Regards Petr> > #sum 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])}} > > Cheers, > R > -- > View this message in context:http://www.nabble.com/how-to-speed-up-this-for-> loop--tp18579577p18579577.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guidehttp://www.R-project.org/posting-guide.html> and provide commented, minimal, self-contained, reproducible code.
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])}} -- View this message in context: http://www.nabble.com/how-to-speed-up-this-for-loop--tp18579577p18592932.html Sent from the R help mailing list archive at Nabble.com.
> -----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