【问题标题】:In R how can I make the for loop run faster?在 R 中,如何使 for 循环运行得更快?
【发布时间】:2021-07-07 00:13:17
【问题描述】:

我有以下代码,属于 2 个时间序列。 maxNo 是时间序列中的元素数。 longStopPrev 是 longStop 的 1 位滞后版本。变量在循环之前启动,因此它们的大小不会在每次迭代中增加。当 maxNo 很大时,这个循环需要很长时间才能运行。

有什么聪明的方法可以避免使用 for 循环和矢量化,或者让它运行得更快吗?

我认为主要的挑战是变量longStopPrev 在循环的每次运行中都有可能被更改,这使得仅作为向量运行一次操作变得困难。但是可能有更好的执行方式,类似于不同的搜索算法。

我已经使用foreach 进行了测试,但它只会让代码运行得更慢。我还测试了 for 循环内的更改

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

与:

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

但结果稍微慢了一点。

我试图在下面制作一个可重现的示例。我在我的时间序列中使用 ~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

【问题讨论】:

  • 首先,在进入循环之前执行longStop &lt;- numeric(maxNo) - 这样您就不会动态增加向量大小,这很昂贵。
  • 如果你做了一个可重现的例子,回答这个问题会更容易。
  • 与其要求我们下载导入一些数据文件,不如让您的示例在问题中独立。要么提供代码来模拟一些示例数据,使用内置数据集,要么与dput(your_data[1:10, ])共享几行数据副本/粘贴。
  • 在某些情况下,是的。在没有看到示例数据的情况下,我很难真正了解您的代码的作用。我认为可以使用矢量化 pmaxcummax 或其他东西来代替循环 - 一个 10 行的示例非常适合理解正在发生的事情并尝试简化。
  • 对于增量改进(或获得整体效果),是的,在大数据上进行测试很好,但这是共享几行代码来模拟示例数据的一个很好的用例。某些东西,set.seed(47); n = 1e5; longStop = rnorm(n) 比 Google 驱动器链接更易于分享。对于回答者来说,它的进入门槛较低,它很稳定,使问题成为更好的长期资源,因为数据不会在任何时候消失,如果需要真正测试限制,我们可以将n 调整得更高。跨度>

标签: r performance for-loop time-series vectorization


【解决方案1】:

我发现在 for 循环之前使用 coredata()xts 转换为 matrix 可以大大加快代码速度。与矩阵相比,显然调用 xts 元素要慢得多。在 for 循环结束时,如果需要,您可以转换回 xts

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多