简体   繁体   English

在 R 如何使 for 循环运行得更快?

[英]In R how can I make the for loop run faster?

I have the below code, of 2 time series.我有以下代码,属于 2 个时间序列。 maxNo is the number of elements in the time series. maxNo 是时间序列中的元素数。 longStopPrev is the 1 position lagged version of longStop. longStopPrev 是 longStop 的 1 position 滞后版本。 The variables are initiated before the loop so that their size is not increasing in every iteration.变量在循环之前启动,因此它们的大小不会在每次迭代中增加。 When the maxNo is large, this loop takes a very long time to run.当 maxNo 很大时,这个循环需要很长时间才能运行。

Is there any clever way to avoid using for loop and vectorize or to make this run faster?有没有什么聪明的方法可以避免使用 for 循环和矢量化或让它运行得更快?

I think the main challenge is that there is a chance for the variable longStopPrev to be changed in each run of the loop, which makes it hard to run the operations only one time as a vector.我认为主要的挑战是变量longStopPrev在循环的每次运行中都有可能发生变化,这使得仅将操作作为向量运行一次变得很困难。 However there could be a better way to execute, similar to different search algorithms.然而,可能有更好的执行方式,类似于不同的搜索算法。

I have tested using foreach but it only made the code run slower.我已经使用foreach进行了测试,但它只会使代码运行速度变慢。 I have also tested changing inside the for loop我还测试了在 for 循环中的更改

longStopPrev = stats::lag(longStop, k=1,na.pad = TRUE) # lag 1 

with:和:

longStopPrev[i+1] <- longStop[i]

But the result was slightly slower.但结果稍微慢了一点。

I tried to make a reproducible example below.我试图在下面制作一个可重现的示例。 I test the code with ~10.000 points in my time series and actually want to run with ~100.000 or longer.我在我的时间序列中用 ~10.000 点测试代码,并且实际上希望以 ~100.000 或更长的时间运行。

require("xts")

set.seed(47); n = 1e1;
data <- xts(rnorm(n)+10, 
             order.by = seq(as.POSIXct("2017-05-31 17:00:00"), length=n, by="min"))

diff=0.5
longStop = data - diff

longStopPrev = stats::lag(longStop, k=1,na.pad = TRUE) # lag 1
longStopPrev = na.approx(longStopPrev, rule=2,na.rm = FALSE,maxgap=1) # fill NA values by approx

maxNo <- nrow(longStop)

for(i in 1:maxNo) {
  if(as.numeric(data[i])>as.numeric(longStopPrev[i]) ){
    longStop[i] <- max(longStop[i],longStopPrev[i])
    longStopPrev = stats::lag(longStop, k=1,na.pad = TRUE) # lag 1 
    
  }
}
longStopPrev = na.approx(longStopPrev, rule=2,na.rm = FALSE,maxgap=1) # fill NA values by approx

I found out that converting xts to a matrix before the for loop using coredata() speeds up the code a lot.我发现在 for 循环之前使用coredata()xts转换为matrix可以大大加快代码速度。 Apparently calling xts elements is much slower compared to a matrix.与矩阵相比,显然调用 xts 元素要慢得多。 at the end of the for loop you can just convert back to xts if you need it.在 for 循环结束时,如果需要,您可以将其转换回xts

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM