我有多个以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
答案 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