6

我有 2 个数值向量,一个存储用于计算最大值的值,另一个存储滚动窗口的长度以滚动计算这些最大值。下面是一些示例代码。通常我试图加快system.time中的代码。是否有一些现成的功能或矢量化的方式来做同样的事情?

a <- rep(1:5,20000)
set.seed(123)
b <- rep(sample(1:50),2000)

system.time({
out <- vector(mode='numeric', length=NROW(a))
for(i in seq(a)) {
  if (i-b[i]>=0) out[i] <- max(a[(i-b[i]+1):i])
  else out[i] <- NA
}
})
4

2 回答 2

1

设法对其部分进行矢量化:

原来的 -

system.time({
  out <- vector(mode='numeric', length=NROW(a))
  for(i in seq(a)) {
    if (i-b[i]>=0) out[i] <- max(a[(i-b[i]+1):i])
    else out[i] <- NA
  }
})
## user  system elapsed 
## 0.64    0.00    0.64 

稍微矢量化 -

system.time({
  nr <- NROW(a)
  out <- rep(NA,nr)
  m <- 1:nr - b + 1
  n <- (1:nr)[m>0]

  for(i in n)
    out[i] <- max(a[m[i]:i])
})
## user  system elapsed 
## 0.39    0.00    0.39 
于 2013-04-26T10:23:44.563 回答
0

您可以对这个问题的各个部分进行矢量化,尤其是在您需要找出a(我称之为 this str)中的起始索引位置和窗口结束(end)的地方,但我必须使用循环构造将这些索引位置应用a到采取max使用mapply。像这样:

x <- seq_len( length(a) )
end <- which( x-b > 0 )
str <- end - b[end]
res <- a
res[ - end ] <- NA
res[end] <- mapply( function(x,y) max( a[ x:y ] ) , str , end )

并与@e4e5f4 的答案进行比较:

identical( res , out )
[1] TRUE

然而,它并没有那么快:

user  system elapsed 
0.46    0.00    0.47

如果有办法对最后一个操作进行矢量化,那么这将非常快,但我现在想不出任何方法来做到这一点!

于 2013-04-26T13:12:26.657 回答