2013-04-26 3 views
6

У меня есть 2 числовых вектора, один из которых хранит значения для вычисления максимума, а другие длины окна прокатки для вычисления этих максимумов на основе проката. Ниже приведен пример кода. Обычно я пытаюсь ускорить код внутри system.time. Есть ли какая-то готовая функция или векторизованный способ сделать то же самое?Каков самый быстрый способ в R рассчитать максимальную скорость прокатки с переменным размером окна прокатки?

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 
} 
}) 
+0

+1 Хороший вопрос. Это интересная проблема, чтобы попытаться оптимизировать! –

ответ

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 
+0

Спасибо, теперь код выглядит лучше – user1603038

+0

+1 Хорошее решение –

0

Вы можете vectorise части этой проблемы, особенно там, где вам нужно чтобы узнать начальную позицию индекса в a (я назвал это 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 «s ответ:

identical(res , out) 
[1] TRUE 

Однако это не совсем так быстро:

user system elapsed 
0.46 0.00 0.47 

Если есть способ vectorise последняя операция, тогда это было бы очень быстро, но я не могу придумать никакого способа сделать это в данный момент!

Смежные вопросы