Есть ли способ сделать что-то вроде align.time () в обратном порядке? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть несколько переменных данных, которые собираются с 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

Однако я бы предпочел, чтобы timesnap произвел это:

>        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 голосов
/ 23 сентября 2018

Я посмотрел на align.time, и вам нужна версия align.time.POSIXct.Теперь я бы предположил, что вы можете указать отрицательное n, но вы не можете.

Но вы можете сделать две вещи, создать свою собственную функцию align.time или использовать floor_date из пакета lubridate.Это будет округлять до ближайшего подразделения.Проверьте ?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 временных меток приводит к тому, что использование функции выравнивания происходит намного быстрее, и чем больше записей, тем быстрее это будет по сравнению с floor_date.Конечно, floor_date имеет много проверок для проверки правильности объектов datetime, юнит-проверок и т. Д. И т. Д.

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
...