5

我正在使用从上午 9:50 开始的日内数据,并希望将其转换为 20 分钟的时间间隔,因此第一个时间段将从 09:50 到 10:09:59,第二个时间段将从 10 点开始: 10 到 10:29:59 等。但是to.minutes(),从xts包裹似乎可以将其固定到小时,并且在 09:59:59 和 10:19:59 等有时间条......即它是 10 分钟......我知道它可能不是一个常规的请求......但是有没有这样做,以便它具有正确的端点,即基于第一个时间戳?

对于奖励积分......有没有办法根据最终时间戳来做到这一点?(即生成从该时间戳向后的周期端点?

这是我关于10分钟后的观点的说明(从我想要的)

x <- xts(rnorm(24*60*60), as.POSIXct(format(paste(Sys.Date(),'09:50')))-((24*60*60):1))
head(x)
x1 <- to.minutes(x, 20)
head(x1)

我可以想办法通过使用 splits、cuts、lapplys do.calls 和 rbinds 来纠正这个问题......但我基本上会重新创建一个 OHLC 对象......并且觉得与现有的相比它可能效率低下解决方案...

4

2 回答 2

6

这是一个有用的技巧,它可能在 xts 文档中更为突出。

从一个xts对象开始

R> set.seed(42)   ## fix seed
R> X <- xts(cumsum(rnorm(100))+100, order.by=Sys.time()+cumsum(runif(100)))
R> head(X)
                              [,1]
2012-10-05 06:42:20.299761 101.371
2012-10-05 06:42:20.816872 100.806
2012-10-05 06:42:21.668803 101.169
2012-10-05 06:42:22.111599 101.802
2012-10-05 06:42:22.269479 102.207
2012-10-05 06:42:22.711804 102.100

鉴于这个不规则序列,我们希望以我们强加的规则间隔进行子集化。在这里,我创建了一个两秒的间隔。如果它与索引的类型相同,则任何其他都可以工作,here POSIXct

R> ind <- seq(start(X) - as.numeric(start(X)-round(start(X))) + 1, 
+             end(X), by="2 secs")
R> head(ind)
[1] "2012-10-05 06:42:21 CDT" "2012-10-05 06:42:23 CDT" 
[3] "2012-10-05 06:42:25 CDT" "2012-10-05 06:42:27 CDT" 
[5] "2012-10-05 06:42:29 CDT" "2012-10-05 06:42:31 CDT"
R> 

现在的诀窍是将规则序列与不规则序列合并,调用na.locf()它以将最后一个好的不规则 obs 调用到新的时间网格上——然后在时间网格上进行子集化:

R> na.locf(merge(X, xts(,ind)))[ind]
                           X
2012-10-05 06:42:21 100.8063
2012-10-05 06:42:23 102.1004
2012-10-05 06:42:25 105.4730
2012-10-05 06:42:27 107.2635
2012-10-05 06:42:29 104.9588
2012-10-05 06:42:31 101.7505
2012-10-05 06:42:33 104.6884
2012-10-05 06:42:35 103.6441
2012-10-05 06:42:37 101.6476
2012-10-05 06:42:39  98.6246
2012-10-05 06:42:41  97.9922
2012-10-05 06:42:43  97.7545
2012-10-05 06:42:45 101.0187
2012-10-05 06:42:47  98.0331
2012-10-05 06:42:49 100.7752
2012-10-05 06:42:51 103.0702
2012-10-05 06:42:53 102.6578
2012-10-05 06:42:55 103.1342
2012-10-05 06:42:57 103.4714
2012-10-05 06:42:59 102.3683
2012-10-05 06:43:01 105.0394
2012-10-05 06:43:03 103.9775
R> 

瞧。

于 2012-10-05T11:46:13.773 回答
4

我最近遇到了类似的挑战(在下午 5 点开始之前拆分外汇数据)。从您的测试数据开始:

library(xts)
set.seed(42)
x <- xts(rnorm(24*60*60), as.POSIXct(format(paste(Sys.Date(),'09:50')))-((24*60*60):1))

将其向后移动 10 分钟,进行拆分,然后将拆分数据向前移动 10 分钟:

offset <- 600
index(x) <- index(x) - offset
x1 <- to.minutes(x, 20)
index(x1) <- index(x1) + offset

(注意,这会损坏x;要么在副本上工作,要么在index(x) <- index(x) + offset之后再做)。x1好像:

                        x.Open   x.High     x.Low    x.Close
2012-10-06 10:09:59  1.3709584 3.495304 -3.371739  0.4408241
2012-10-06 10:29:59 -0.7465165 3.584659 -2.828475  0.5938161
2012-10-06 10:49:59  1.3275046 3.174520 -3.199558 -0.6273660
...
2012-10-07 09:09:59 -0.83742490 3.103466 -3.251721 -1.093380
2012-10-07 09:29:59 -0.48464537 3.228048 -3.113351 -1.572931
2012-10-07 09:49:59  1.90503697 3.420940 -3.505207  2.832325

神奇的数字 600 出现了,因为您的最后一次滴答是距离前 20 分钟边界的 600 秒。以下是您如何动态计算它:

offset <- ( as.integer(last(index(x))) %% 1200 ) + 1

as.integer将最后一个刻度的时间转换为 secs-since-1970 形式。(as.numeric如果您的时间戳中有毫秒,则使用。)%%1200向下舍入到 20 分钟边界。最后,这+1是因为to.minutes将 XX:XX:00 视为一个小节的开始,而不是前一个小节的结束

于 2012-10-07T01:47:33.727 回答