I think you only have to calculate
X.cum.sum[1:i]-seq(1:i)*X.cum.mean[i]
once for the entire vector since it appears that you are just computing it
over and over again for lengthing vectors. Here I have just computed it
once and then did a running min/max on the data. This should run faster:
system.time({
X <- rnorm(10000)
X.length <- length(X)
X.cum.sum <- cumsum(X)
X.cum.mean <- cumsum(X) # didn't have a cummean
# create matrix of precalculated values (they are in the min/max columns)
myMat <- cbind(newmean=X.cum.sum - (X.cum.mean * seq(X.length)), max=NA,
min=NA)
# now put min/max in columns; start with initial value
myMat[1, c('max', 'min')] <- myMat[1, 'newmean']
for (i in 2:nrow(myMat)){
# determine the running min/max
if (myMat[i, 'newmean'] > myMat[i-1, 'max']) myMat[i,
'max'] <- myMat[i,
'newmean']
else myMat[i, 'max'] <- myMat[i-1, 'max']
if (myMat[i, 'newmean'] < myMat[i-1, 'min']) myMat[i,
'min'] <- myMat[i,
'newmean']
else myMat[i, 'min'] <- myMat[i-1, 'min']
}
})
On 3/12/07, Oliver Faulhaber <oliverfaulhaber@gmx.de>
wrote:>
> Hi all,
>
> as I am trying to move slowly from just "working" to
"good" code, I'd
> like to ask if there's a smarter way than using a for-loop in tasks
like
> the example below.
>
> I need to obtain the extrema of the cumulated sum of a detrended time
> series. The following code is currently used, please have a look at the
> comments for my questions and remarks:
>
> system.time({
> X <- rnorm(10000)
> X.length <- length(X)
> X.cum.sum <- cumsum(X)
> X.cum.mean <- cummean(X)
> # initializing the "output" vectors
> X.min.detrended <- rep(NA,X.length)
> X.max.detrended <- rep(NA,X.length)
> for (i in 1:X.length) {
> # Detrending of the time series from index 1 to i
> # I think that's the time consuming part, are there any
> # suggestions how to do this faster?
> X.cum.sum.detrended <- X.cum.sum[1:i]-seq(1:i)*X.cum.mean[i]
> # Calculating the min and max. Would a "range" be smarter here?
> X.min.detrended[i] <- min(X.cum.sum.detrended)
> X.max.detrended[i] <- max(X.cum.sum.detrended)
> # As the programs takes rather long to complete I would like to
> # get information about the progress. Any better way to do this
> # than a cat(paste(i,"...",""))?
> }
> })
>
> As you can see this takes rather long even for this relative small sample:
>
> [1] 41.11 0.97 45.14 NA NA
>
> I considered using "sapply", but expected problems with memory
size as a
> lot more values have to be kept in memory (the typical length of X is
> 10^6 - 10^7).
>
> Thanks again for your patience with newbies like me :)
>
> Regards
> Oliver
>
> ______________________________________________
> R-help@stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
--
Jim Holtman
Cincinnati, OH
+1 513 646 9390
What is the problem you are trying to solve?
[[alternative HTML version deleted]]