加快 R 中大型数组的平方误差计算速度



>基本上,我正在帮助某人为他们的研究编写一些代码,但我通常节省时间的策略并没有减少她的算法的运行时间,以至于它是合理的。 我希望其他人可能知道一种更好的方法,根据我编写的示例使函数快速运行,以避免包含有关研究的信息。

示例中的对象比她正在使用的对象小(但可以很容易地放大(。 对于实际算法,这块在小情况下大约需要 3 分钟,但在完整情况下可能需要 8-10 分钟,并且可能需要运行 1000-10000 次。 这就是我需要认真减少运行时间的原因。

我目前是如何做到这一点的(希望有足够的评论来让我的思维过程变得明显(:

example<-array(rnorm(100000), dim=c(5, 25, 40, 20))
observation <- array(rnorm(600), dim=c(5, 5, 12))
calc.err<-function(value, observation){
  #'This creates the squared error for each observation, and each point in the
  #'example array, across the five values in the first dimension of each
  sqError<-(value-observation)^2
  #'the apply function here sums up the squared error for each observation and
  #'point.  This is the value returned
  return(apply(sqError, c(2,3), function(x) sum(x)))
}
run<-apply(example, c(2,3,4), function(x) calc.err(x, observation))
#'It isn't returned in the right format (small problem) but reformatting is fast
format<-array(run, dim=c(5, 12, 25, 40, 20))

如有必要,将澄清。

编辑:data.table 包似乎非常有用。我将不得不学习这个包,但初步工作似乎要快得多。我想我正在使用数组,因为她给我的代码使对象以这种方式格式化。甚至没有想过改变它

以下是几个简单的重构以及计时:

calc.err2 <- function(value, observation){
  #'This creates the squared error for each observation, and each point in the
  #'example array, across the five values in the first dimension of each
  sqError<-(value-observation)^2
  #' getting rid of the anonymous function
  apply(sqError, c(2,3), sum)
}
calc.err3 <- function(value, observation){
  #'This creates the squared error for each observation, and each point in the
  #'example array, across the five values in the first dimension of each
  sqError<-(value-observation)^2
  #' replacing with colSums
  colSums(sqError)
}

R>microbenchmark(times=8, apply(example, 2:4, calc.err, observation),
+   apply(example, 2:4, calc.err2, observation),
+   apply(example, 2:4, calc.err3, observation)
+ )
Unit: milliseconds
                                        expr         min          lq
  apply(example, 2:4, calc.err, observation) 2284.350162 2321.875878
 apply(example, 2:4, calc.err2, observation) 2194.316755 2257.007572
 apply(example, 2:4, calc.err3, observation)  645.004808  652.567611
         mean       median           uq         max neval
 2349.7524509 2336.6661645 2393.3452420 2409.894876     8
 2301.7896566 2298.9346090 2362.5479790 2383.020177     8
  681.3176878  667.9070175  720.7049605  723.177516     8

colSums比相应的apply快得多。

最新更新