我有一个xts
对象,如下所示:
> q.xts
val
2011-08-31 09:30:00.002357 -1.0135222
2011-08-31 09:30:00.003443 -0.2182679
2011-08-31 09:30:00.005075 -0.5317191
2011-08-31 09:30:00.009515 -1.0639535
2011-08-31 09:30:00.011569 -1.2470759
2011-08-31 09:30:00.012144 0.7678103
2011-08-31 09:30:00.023813 -0.6303432
2011-08-31 09:30:00.024107 -0.5105943
我计算了另一个数据框r
中的时间戳的固定偏移量。 r
中的行数明显少于q.xts
中的行数。
> r
time predict.time
1 2011-08-31 09:30:00.003443 2011-08-31 09:30:00.002443
2 2011-08-31 09:30:00.009515 2011-08-31 09:30:00.008515
3 2011-08-31 09:30:00.024107 2011-08-31 09:30:00.023108
time
列对应于来自q.xts
的观察,而predict.time
列对应于time
之前的1毫秒(减去任何精确度的舍入)。
我想要做的是找到q.xts
中与predict.time
的每个值相等或更早的最后一个观察点。对于上面r
中的三个观察,我希望得到以下匹配:
time predict.time (time from q.xts)
1 2011-08-31 09:30:00.003443 2011-08-31 09:30:00.002443 --> 09:30:00.002357
2 2011-08-31 09:30:00.009515 2011-08-31 09:30:00.008515 --> 09:30:00.005075
3 2011-08-31 09:30:00.024107 2011-08-31 09:30:00.023108 --> 09:30:00.012144
我通过循环遍历r
中的每一行并执行xts subset
来解决此问题。因此,对于r
的第1行,我会这样做:
> last(index(q.xts[paste('/', r[1,]$predict.time, sep='')]))
[1] "2011-08-31 09:30:00.002357 CDT"
问题:使用循环执行此操作似乎很笨拙和笨拙。有没有更好的办法?我想在r
中添加另一列,其中提供q.xts
中相应值的确切时间或行号。
注意:使用它来构建我在此示例中使用的数据:
q <- read.csv(tc <- textConnection("
2011-08-31 09:30:00.002358, -1.01352216
2011-08-31 09:30:00.003443, -0.21826793
2011-08-31 09:30:00.005076, -0.53171913
2011-08-31 09:30:00.009515, -1.06395353
2011-08-31 09:30:00.011570, -1.24707591
2011-08-31 09:30:00.012144, 0.76781028
2011-08-31 09:30:00.023814, -0.63034317
2011-08-31 09:30:00.024108, -0.51059425"),
header=FALSE); close(tc)
colnames(q) <- c('datetime', 'val')
q.xts <- xts(q[-1], as.POSIXct(q$datetime))
r <- read.csv(tc <- textConnection("
2011-08-31 09:30:00.003443
2011-08-31 09:30:00.009515
2011-08-31 09:30:00.024108"),
header=FALSE); close(tc)
colnames(r) <- c('time')
r$time <- as.POSIXct(strptime(r$time, '%Y-%m-%d %H:%M:%OS'))
r$predict.time <- r$time - 0.001
答案 0 :(得分:4)
可能有更好的方法可以做到这一点,但这是我现在能想到的最好方法。
# create an empty xts object based on r$predict.time
r.xts <- xts(,r$predict.time)
# merge q.xts and r.xts. This will insert NAs at the times in r.xts.
tmp <- merge(q.xts,r.xts)
# Here's the magic:
# lag tmp *backwards* one period, so the NAs appear at the times
# right before the times in r.xts. Then grab the index for the NA periods
tmp.index <- index(tmp[is.na(lag(tmp,-1,na.pad=FALSE))])
# get the rows in q.xts for the times in tmp.index
out <- q.xts[tmp.index]
# val
# 2011-08-31 09:30:00.002357 -1.0135222
# 2011-08-31 09:30:00.005075 -0.5317191
# 2011-08-31 09:30:00.012144 0.7678103
答案 1 :(得分:2)
我会使用findInterval
:
findInterval(r$predict.time, index(q.xts))
> q.xts[findInterval(r$predict.time, index(q.xts)),]
val
2011-08-31 09:30:00 -1.0135222
2011-08-31 09:30:00 -0.5317191
2011-08-31 09:30:00 0.7678103
您的时间是POSIXct
所以这应该相当健壮。