在start =和end =上向量化window.zoo

时间:2015-02-14 16:56:29

标签: r vectorization zoo

我输入的数据看起来像那样(例子减少到两个时间序列)。

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')))

我正在尝试编写一个函数,对于每个时间序列(x [,i]),平均由begin [i]和end [i]定义的窗口的值。

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

如果提供了单个时间序列,但上面的函数(或略微修改的版本)有效,但未在beginend上正确地进行矢量化。知道我怎么能做这个工作吗?

# 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))  
}

谢谢, 卢瓦克

3 个答案:

答案 0 :(得分:2)

创建要使用的zoo对象,将其转换为zoo对象列表,并将Map(或mapply)转换为它。

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

请注意,关键是使用as.list,而不是list

答案 1 :(得分: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)
}

答案 2 :(得分:0)

另一个答案真正展示了矢量化解决方案如何为for循环做任何事情。

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