R找到时间序列动态窗口的最大(或最小)

时间:2014-09-23 10:03:15

标签: r formulas array-formulas

我有一个有两列的时间序列,一列包含一个“信号”NA或者不是(那么它是1到5之间的整数,我不关心实际值,除非它与NA不同)和第二列包含实际值。

我需要计算最高值,因为信号不是NA。这显示在下面的示例中。

    Date        Sig Val     Expected result
    2008-01-01  1   47      47  <<- Sig==1, i. e. here we start counting
    2008-01-02  NA  31      47
    2008-01-03  NA  61      61  <<- 61 is higher than 47, so this one is important now
    2008-01-04  NA  43      61  
    2008-01-05  NA  23      61
    2008-01-06  NA  46      61
    2008-01-07  NA  17      61
    2008-01-08  NA  52      61
    2008-01-09  NA  84      84  <<- a new high, value should be kept
    2008-01-10  NA  54      84
    2008-01-11  1   30      30  <<- a new signal, here we start counting again
    2008-01-12  NA  36      36  <<- a new higher value in this segment
    2008-01-13  NA  59      59  <<- again a new higher value in this segment
    2008-01-14  NA  56      59
    2008-01-15  NA  15      59
    2008-01-16  NA  21      59
    2008-01-17  NA  87      87
    2008-01-18  NA  81      87
    2008-01-19  2   94      94  <<- a new signal this time a 2, so here we start counting again
    2008-01-20  NA  42      94
    2008-01-21  NA  95      95
    2008-01-22  1   42      42  <<- a new signal, here we start counting again
    2008-01-23  NA  25      42
    2008-01-24  NA  20      42
    2008-01-25  NA  76      76
    2008-01-26  NA  95      95
    2008-01-27  NA  14      95
    2008-01-28  NA  12      95
    2008-01-29  NA  13      95
    2008-01-30  NA  57      95
    2008-01-31  NA  26      95

问题是相关的观察窗口是动态的,具体取决于信号列。

我玩过runMax(),cummax()和rollapply()函数,但它们只能在特定的窗口长度上工作......我想我看不到树木,但我可以弄清楚如何使“回顾”窗口动态化。有什么猜测吗?

2 个答案:

答案 0 :(得分:4)

创建一个用于创建信号组的列,然后使用cummax

使用data.table(假设您的数据位于data.frame df)

library(data.table)

D <- as.data.table(df)
D[, list(maxvalue = cummax(value)), 
    by = list(sig2 = cumsum(replace(sig, is.na(sig), 0)))]

答案 1 :(得分:0)

同样可以使用dplyr

说您有一个带有信号和价格的tibble

df<-tibble(
  px=c(1,cumprod(exp(rnorm(999,mean=0.0001,sd=0.01)))),
  sig=runif(length(px))>0.95
) 

按期间分组并应用cummax的工作原理是:(分组列 已创建)

mutate(group_by(df,g=cumsum(sig)),rmax=cummax(px))

或者,accumulate2无需分组即可工作

mutate(df,rmax=unlist(accumulate2(px,tail(sig,-1),~..3*..1+(1-..3)*max(..1,..2))))

这有点灵活,功能可以适应 更详尽的滚动计算