R:如何在毫秒级重新采样日期时间变量?

时间:2016-12-30 20:18:34

标签: r datetime dplyr xts lubridate

我有一个类似以下的数据框

library(dplyr)
library(lubridate)
time = c('2013-01-03 22:04:21.549', '2013-01-03 22:04:21.549', '2013-01-03 22:04:21.559', '2013-01-03 22:04:23.559' )
value = c(1,2,3,4)

data <- data_frame(time, value)
data <-data %>%  mutate(time = ymd_hms(time))

# A tibble: 4 × 2
                     time value
                   <dttm> <dbl>
1 2013-01-03 22:04:21.549     1
2 2013-01-03 22:04:21.549     2
3 2013-01-03 22:04:21.559     3
4 2013-01-03 22:04:23.559     4

我想每200 <毫秒> 重新采样此数据帧。

即,每200毫秒取value的平均值。

我知道可以lubridate::floor_date(time, '1 second')使用second精度,但不能milliseconds

在上面的示例中,行123应该组合在一起,而行4应该是唯一的(注意它是2距离其他人几秒钟。)

有什么想法吗? 谢谢!

2 个答案:

答案 0 :(得分:3)

由于您使用了[xts]标记,因此这是一个xts解决方案:

options(digits.secs=6)
require(xts)
x <- xts(1:4, as.POSIXct(c('2013-01-03 22:04:21.549', '2013-01-03 22:04:21.549',
                           '2013-01-03 22:04:21.559', '2013-01-03 22:04:23.559')))
period.apply(x, endpoints(x, "ms", 200), mean)
#                         [,1]
# 2013-01-03 22:04:21.559    2
# 2013-01-03 22:04:23.559    4

data对象开始:

x <- with(data, xts(value, time))
period.apply(x, endpoints(x, "ms", 200), mean)

答案 1 :(得分:2)

您对xts解决方案的评论要求将其“插回”数据框这一事实使我认为您要么需要合并结果,要么需要按时间分组列。这就是ave函数在基数R中的作用。可能有一个dplyr等价物,但我更像是一个基础R家伙: 编辑:

 data$ms200mn <- ave(data$value, 
                     cut( arg <- as.numeric(data$time) , 
                                breaks=seq( floor(arg[1]), ceil(arg[4]), by=0.2) ),
                     FUN=mean)
>  data
# A tibble: 4 × 3
                 time value ms200mn
               <dttm> <dbl>   <dbl>
1 2013-01-03 22:04:21     1       2
2 2013-01-03 22:04:21     2       2
3 2013-01-03 22:04:21     3       2
4 2013-01-03 22:04:23     4       4

这实际上并没有被称为“采样”(或重新采样),而是聚合seq.POSIXt - 函数没有'msec'选项(因此需要转换为数字秒),不允许小数秒。

解释:

cut(arg <- as.numeric(data$time), breaks=seq( floor(arg[1]), ceil(arg[4]), by=0.2) )

它是在由第一个项目下方和最后一个项目上方结束的中断序列定义的组中“分类”或“分类”项目。需要创建arg - 值,因为(出于我不理解的原因)seq函数可以使用原始'datetime'变量。