有没有办法像align.time()那样做相反的事情?

时间:2018-09-12 00:20:02

标签: r time-series posix xts

我有多个以15分钟为间隔收集的数据变量,但是其中一些变量的时间戳略有偏差,因为各种传感器中的内部时钟未完全对齐。为了轻松合并各种度量,我想将所有时间戳对齐到最接近的15分钟标记。

我想使用xts :: align.time()之类的东西,但是此功能始终会向前捕捉。我希望能够使用智能四舍五入规则向后捕捉,甚至更好。我该怎么办?

这是我想使用align.time()做的示例代码:

require(xts)
require(dplyr)

timestamps <- as.data.frame(as.POSIXlt.character(c("2017-09-11 00:01:39", 
"2017-09-11 00:16:39", "2017-09-11 00:31:39", "2017-09-11 00:46:39"), tz 
= "", format = "%Y-%m-%d %H:%M:%S"))
values <- as.data.frame(as.numeric(c(1,2,6,0.5)))
variable <- as.data.frame(rep("Chloride", 4))

df <- cbind(timestamps, values, variable); names(df) <- c("DateTime_UTC", 
"Value", "Variable")

df %>%
  mutate(DateTime_UTC = align.time(DateTime_UTC, n = 60 * 15))

>        DateTime_UTC Value Variable
>1 2017-09-11 00:15:00   1.0 Chloride
>2 2017-09-11 00:30:00   2.0 Chloride
>3 2017-09-11 00:45:00   6.0 Chloride
>4 2017-09-11 01:00:00   0.5 Chloride

但是我更希望使用时间间隔来产生这种效果:

>        DateTime_UTC Value Variable
>1 2017-09-11 00:00:00   1.0 Chloride
>2 2017-09-11 00:15:00   2.0 Chloride
>3 2017-09-11 00:30:00   6.0 Chloride
>4 2017-09-11 00:45:00   0.5 Chloride

1 个答案:

答案 0 :(得分:0)

我查看了align.time,您需要的版本是align.time.POSIXct。现在,我假设您可以提供负数n,但您不能。

但是您可以做两件事,创建自己的align.time函数或使用lubridate软件包中的floor_date。这将舍入到最接近的单位。检查?floor_date中所有可能的选项。

创建自己的功能就像我在下面所做的那样。我刚刚从align.time.POSIXct中删除了负面限制,并创建了函数my_align_time

my_align_time <- function(x, n = 60) {
  structure(unclass(x) + (n - unclass(x) %% n), class=c("POSIXct","POSIXt"))
}

library(lubridate)
library(dplyr)

df %>%
  mutate(use_floor_date = floor_date(DateTime_UTC, unit = "15 mins"),
         use_my_align_time = my_align_time(DateTime_UTC, n = 60 * -15))

         DateTime_UTC Value Variable           use_floor        use_my_align
1 2017-09-11 00:01:39   1.0 Chloride 2017-09-11 00:00:00 2017-09-11 00:00:00
2 2017-09-11 00:16:39   2.0 Chloride 2017-09-11 00:15:00 2017-09-11 00:15:00
3 2017-09-11 00:31:39   6.0 Chloride 2017-09-11 00:30:00 2017-09-11 00:30:00
4 2017-09-11 00:46:39   0.5 Chloride 2017-09-11 00:45:00 2017-09-11 00:45:00

当然,现在的问题是哪个更快?使用1000个时间戳,结果是使用align函数比floor_date快得多,并且记录越多,速度就越快。当然floor_date里面有很多检查,以检查日期时间对象是否正确,单位检查等。

library(microbenchmark)
x <- Sys.time() + 1:1000

microbenchmark(floor = floor_date(x, unit = "15 mins"),
               align = my_align_time(x, n = -60 * 100))

Unit: microseconds
  expr      min       lq       mean   median       uq      max neval
 floor 4598.913 4670.447 4738.57723 4728.228 4781.770 5188.149   100
 align   25.454   27.210   32.61044   31.305   33.646   75.484   100