滚动窗口在不规则的时间序列

时间:2012-05-11 18:07:47

标签: r time-series xts zoo

我使用xts有一个不规则的时间序列事件(帖子),我想计算在滚动的每周窗口(或每两周,或3天等)发生的事件的数量。数据如下所示:

                    postid
2010-08-04 22:28:07    867
2010-08-04 23:31:12    891
2010-08-04 23:58:05    901
2010-08-05 08:35:50    991
2010-08-05 13:28:02   1085
2010-08-05 14:14:47   1114
2010-08-05 14:21:46   1117
2010-08-05 15:46:24   1151
2010-08-05 16:25:29   1174
2010-08-05 23:19:29   1268
2010-08-06 12:15:42   1384
2010-08-06 15:22:06   1403
2010-08-07 10:25:49   1550
2010-08-07 18:58:16   1596
2010-08-07 21:15:44   1608

应该产生类似

的东西
                    nposts
2010-08-05 00:00:00     10
2010-08-06 00:00:00      9
2010-08-07 00:00:00      5

为期2天的窗口。我查看了来自rollapply等的apply.rollingPerformanceAnalytics,并且他们都假设了常规的时间序列数据。我尝试将所有时间更改为帖子发生的那一天,并使用类似ddply的内容在每天进行分组,这让我很接近。但是,用户可能不会每天发布,因此时间序列仍然是不规则的。我可以用0填补空白,但这可能会使我的数据大量膨胀,而且已经非常大了。

我该怎么办?

3 个答案:

答案 0 :(得分:5)

这是使用xts的解决方案:

x <- structure(c(867L, 891L, 901L, 991L, 1085L, 1114L, 1117L, 1151L, 
  1174L, 1268L, 1384L, 1403L, 1550L, 1596L, 1608L), .Dim = c(15L, 1L),
  index = structure(c(1280960887, 1280964672, 1280966285, 
  1280997350, 1281014882, 1281017687, 1281018106, 1281023184, 1281025529, 
  1281050369, 1281096942, 1281108126, 1281176749, 1281207496, 1281215744),
  tzone = "", tclass = c("POSIXct", "POSIXt")), class = c("xts", "zoo"),
  .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", "POSIXt"),
  .indexTZ = "", tzone = "")
# first count the number of observations each day
xd <- apply.daily(x, length)
# now sum the counts over a 2-day rolling window
x2d <- rollapply(xd, 2, sum)
# align times at the end of the period (if you want)
y <- align.time(x2d, n=60*60*24)  # n is in seconds

答案 1 :(得分:4)

这似乎有效:

# n = number of days
n <- 30
# w = window width. In this example, w = 7 days
w <- 7

# I will simulate some data to illustrate the procedure
data <- rep(1:n, rpois(n, 2))

# Tabulate the number of occurences per day:
# (use factor() to be sure to have the days with zero observations included)
date.table <- table(factor(data, levels=1:n))  

mat <- diag(n)
for (i in 2:w){
  dim <- n+i-1
  mat <- mat + diag(dim)[-((n+1):dim),-(1:(i-1))]
  }

# And the answer is.... 
roll.mean.7days <- date.table %*% mat

似乎不会太慢(尽管mat矩阵将得到尺寸n * n)。我试图用n = 3000替换n = 30(这创建了一个900万个元素的矩阵= 72 MB),它在我的计算机上仍然是合理的。对于非常大的数据集,首先尝试子集....使用Matrix包中的一些函数(bandSparse)来创建mat矩阵也会更快。

答案 2 :(得分:0)

有亚军的人可以在滚动窗口上apply any R function。 OP要求的是仅在指定时间点在滚动窗口上计算函数(长度)。 使用runner的用户需要指定at参数来指示应该在哪个时间点上计算输出。我们只需将时间点的向量传递到runner序列中就在一侧创建的POSIXt
要使runner与时间相关,必须通过与idx对象相对应的日期指定x。窗口长度可以设置为k = "2 days"

at <- seq(as.POSIXct("2010-08-05 00:00:00"), 
          by = "1 days",
          length.out = 4)

# [1] "2010-08-05 CEST" "2010-08-06 CEST" "2010-08-07 CEST" "2010-08-08 CEST"


runner::runner(
  x = x$postid,
  k = "2 days",
  idx = x$datetime,
  at = at,
  f = length
)
# [1]  3 10  9  5