2015-02-14 4 views
2

У меня есть входные данные, которые выглядят так (сокращены до двух временных рядов для примера).Vectorize window.zoo over start = и end =

library(zoo) 
begin <- as.Date(c('2003-02-12', '2003-01-23')) 
end <- as.Date(c('2003-10-02', '2003-08-01')) 
x.Date <- as.Date("2003-01-01") + seq(1, 365, 8) - 1 
data <- matrix(rnorm(length(x.Date)*2), ncol = 2, dimnames = list(r = NULL, col = c('a', 'b'))) 

Я пытаюсь написать функцию, которая для каждого временного ряда (х [, я]), средние значения для окна, определенного начала [I] и конец [я].

fun <- function(data, begin, end, dates) { 
    x <- zoo(data, dates) 
    xSub <- window(x, start = begin, end = end) 
    colMeans(xSub, na.rm = TRUE) 
} 

Функция выше (или немного модифицированный вариант) работает, если один временной ряд предоставляется, но не должным образом векторизованы над begin и end. Любая идея, как я мог бы сделать эту работу?

# Slightly modified version working for single time-series 
fun2 <- function(data, begin, end, dates) { 
    x <- zoo(data, dates) 
    xSub <- window(x, start = begin, end = end) 
    mean(xSub, na.rm = TRUE) 
} 

fun2(data[,1], begin[1], end[1], x.Date) # OK 

fun(data, begin, end, x.Date) # Same window is used for both time-series 

Функция должна воспроизводить поведение этого цикла.

out <- c() 
for(i in 1:ncol(data)) { 
    x <- zoo(data[,i], x.Date) 
    xSub <- window(x, start = begin[i], end = end[i]) 
    out <- c(out, mean(xSub)) 
} 

Спасибо, Лоик

+0

Вы хотите передать вектор начальных значений и вектор конечных значений, а функция возвращает вектор, значения которого являются результатом пар-парных оценок? –

+0

@ J.Won. Это именно то, чего я пытаюсь достичь. Я отредактировал вопрос, чтобы проиллюстрировать это. –

+1

Возможно, см. 'Mapply':' mapply (function (j, b, e) fun2 (data [, j], b, e, x.Date), seq_len (ncol (data)), begin, end) ' –

ответ

2

Создать объект зоопарк будет использоваться, преобразовать его в список объектов зоопарка и Map (или mapply) над ним.

z <- zoo(data, x.Date) 
Map(window, as.list(z), start = begin, end = end) 

Обратите внимание, что ключ использовать as.list, не list.

+0

Очень элегантное решение, спасибо –

0

Альтернативного ответ, который на самом деле показывает, как Векторизованное решение может сделать что-нибудь для цикла делает.

fun <- function(data, begin, end, dates) { 
    x <- zoo(data, dates) 
    paircount <- 1:length(begin) 
    sapply(paircount, function(i) mean(window(x[,i], start=begin[i], end=end[i]), na.rm=TRUE)) 
} 
+0

Спасибо, мне нравится этот, хорошо работает. Немного отредактирован. –

1

mapply, вероятно, лучший способ это сделать.

fun <- function(data, begin, end, dates) { 
    x <- zoo(data, dates) 
    step1 <- mapply(window, start=begin, end=end, MoreArgs=list(x=x)) 
    sapply(step1, colMeans, na.rm=TRUE) 
} 
+0

Да, это был мой первоначальный подход. Хотя для работы переменной 'x' в вызове mapply необходимо было бы быть частью переменной, над которой« окно »векторизовано. Но это не так просто, чтобы векторизовать его по правильному размеру 'x'. –

+0

Мы оцениваем каждую пару 'begin' /' end', но только для одного значения 'x'. Вот почему 'x' передается отдельно в списке MoreArgs. –

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