Как восстановить временной ряд, зная промежутки времени между строками (вектор `A`) и время для одного определенного c значения` A` - PullRequest
1 голос
/ 13 апреля 2020

У меня есть вектор Delay, который представляет промежуток времени между различными моментами в секундах. Ниже я приведу небольшой пример:

Delay <- c(120,180,90,110) 

Дело в том, что я хочу пересоздать последовательное время, используя вектор Delay и зная, что время для указанной c позиции Delay (т.е. Задержка [3]) равна 2016-08-30 12:00:00. РЕКОНСТРУКЦИЯ BACKWARDS И FORWARDS ОТЛИЧАЕТСЯ, как вы можете видеть в примере ниже. Начиная с нашего «базового времени», движение в обратном направлении подразумевает вычитание 90 секунд до 2016-08-30 12:00:00. Движение вперед подразумевает добавление 110 секунд к 2016-08-30 12:00:00. Последнее условие заключается в том, что мне нужно только последовательное время между 2 указанными c датами, например, между 2016-08-30 11:38:00 и 2016-08-30 12:19:00 в этом примере.

Что я мог бы ожидать от этого примера, так это:

   Delay            DateTime
1    120 2016-08-30 11:38:50        .                   .                  .
2    180 2016-08-30 11:41:50        .                   .                  .
3     90 2016-08-30 11:43:20        .                   .                  .
4    110 2016-08-30 11:45:10        .                   .                  .
5    120 2016-08-30 11:47:10        .                   .                  .
6    180 2016-08-30 11:50:10        .                   .                  .
7     90 2016-08-30 11:51:40        .                   .                  .
8    110 2016-08-30 11:53:30        .                   .                  .
9    120 2016-08-30 11:55:30  # I have subtracted 180 seconds to the time `2016-08-30 11:58:30`
10   180 2016-08-30 11:58:30  # I have subtracted 90 seconds to the time `2016-08-30 12:00:00`
11    90 2016-08-30 12:00:00  # Starting point from which we move backwards and forwards using the sequence of times specified in `Delay`
12   110 2016-08-30 12:01:50  # I have added 110 seconds to the time `2016-08-30 12:00:00`
13   120 2016-08-30 12:03:50  # I have added 120 seconds to the time `2016-08-30 12:01:50`
14   180 2016-08-30 12:06:50        .                   .                  .
15    90 2016-08-30 12:08:20        .                   .                  .
16   110 2016-08-30 12:10:10        .                   .                  .
17   120 2016-08-30 12:12:10        .                   .                  .
18   180 2016-08-30 12:15:10        .                   .                  .
19    90 2016-08-30 12:16:40        .                   .                  .
20   110 2016-08-30 12:18:30        .                   .                  .

Как я мог себе это позволить?

Применяя код, предложенный @Ian Campbell, но меняя вектор Delay и некоторые сроки, я нахожу это:

Delay <- c(120,180,90,110,150,170) 
KnownTime <-  as_datetime("2016-08-30 12:00:00")
KnownTimePosition <- 3
TargetTimePast <- as_datetime("2016-08-30 11:38:00")
TargetTimeFuture <- as_datetime("2016-08-30 12:13:00")

DelaySpan <- sum(Delay)
TargetPastSeconds <- time_length(KnownTime - TargetTimePast)
TotalSpan <- time_length(TargetTimeFuture - TargetTimePast)
DelaysBack <- ceiling((TargetPastSeconds - sum(Delay[1:(KnownTimePosition)]))/DelaySpan)
TotalDelays <- ceiling(TotalSpan/DelaySpan)
FullDelayVector <- rep(Delay,TotalDelays)
Start <- KnownTime - seconds(sum(Delay[1:(KnownTimePosition)])) - DelaysBack * DelaySpan

Result <- as_datetime(Reduce(function(x,y){x + seconds(y)},FullDelayVector,Start,accumulate = TRUE))
Result <- Result[Result >=  TargetTimePast & Result <=  TargetTimeFuture]

Result <- as.data.frame(Result)
colnames(Result)[1] <- "DateTimeUTC"
Result

foo <- Result %>%
  arrange(DateTimeUTC) %>%
  mutate(diff = as.POSIXct(DateTimeUTC, "%Y-%m-%d %H:%M:%OS") - lag(as.POSIXct(DateTimeUTC, "%Y-%m-%d %H:%M:%OS"), default = as.POSIXct(DateTimeUTC, "%Y-%m-%d %H:%M:%OS")[1]),
         diff_secs = as.numeric(diff, units = 'secs'))
foo

           DateTimeUTC     diff diff_secs
1  2016-08-30 11:39:50   0 secs         0
2  2016-08-30 11:41:50 120 secs       120
3  2016-08-30 11:44:50 180 secs       180
4  2016-08-30 11:46:20  90 secs        90
5  2016-08-30 11:48:10 110 secs       110
6  2016-08-30 11:50:40 150 secs       150
7  2016-08-30 11:53:30 170 secs       170
8  2016-08-30 11:55:30 120 secs       120
9  2016-08-30 11:58:30 180 secs       180
10 2016-08-30 12:00:00  90 secs        90
11 2016-08-30 12:01:50 110 secs       110
12 2016-08-30 12:04:20 150 secs       150
13 2016-08-30 12:07:10 170 secs       170

Как вы видите, начальное время для информационного кадра в порядке, так как я установил в качестве момента отсечки время 2016-08-30 11:38:00, поэтому предыдущая строка первой строки в foo будет 2016-08-30 11:37:00 (вычитая 170 секунд до 2016-08-30 11:38:00), что превышает 2016-08-30 11:38:00, а затем не появляется. Однако для другого предела моего фрейма данных foo я нахожу как в прошлый раз 2016-08-30 12:07:10, когда предел равен 2016-08-30 12:13:00 и, следовательно, должно быть еще несколько строк, использующих Delay в качестве критерия.

1 Ответ

1 голос
/ 13 апреля 2020

Я думаю, что это будет делать то, что вы просите. Мы можем использовать Reduce, чтобы следовать за вектором Delay. Я буду использовать lubridate для удобства

library(lubridate)
Delay <- c(120,180,90,110) 
KnownTime <-  as_datetime("2016-08-30 12:00:00")
KnownTimePosition <- 3
TargetTimePast <- as_datetime("2016-08-30 11:38:00")
TargetTimeFuture <- as_datetime("2016-08-30 12:19:00")

DelaySpan <- sum(Delay)
TargetPastSeconds <- time_length(KnownTime - TargetTimePast)
TotalSpan <- time_length(TargetTimeFuture - TargetTimePast)
DelaysBack <- ceiling((TargetPastSeconds - sum(Delay[1:(KnownTimePosition)]))/DelaySpan)
TotalDelays <- ceiling(TotalSpan/DelaySpan)
FullDelayVector <- rep(Delay,TotalDelays)
Start <- KnownTime - seconds(sum(Delay[1:(KnownTimePosition)])) - DelaysBack * DelaySpan

Result <- as_datetime(Reduce(function(x,y){x + seconds(y)},FullDelayVector,Start,accumulate = TRUE))
Result[Result >=  TargetTimePast & Result <=  TargetTimeFuture]
# [1] "2016-08-30 11:38:50 UTC" "2016-08-30 11:41:50 UTC" "2016-08-30 11:43:20 UTC" "2016-08-30 11:45:10 UTC" "2016-08-30 11:47:10 UTC"
# [6] "2016-08-30 11:50:10 UTC" "2016-08-30 11:51:40 UTC" "2016-08-30 11:53:30 UTC" "2016-08-30 11:55:30 UTC" "2016-08-30 11:58:30 UTC"
#[11] "2016-08-30 12:00:00 UTC" "2016-08-30 12:01:50 UTC" "2016-08-30 12:03:50 UTC" "2016-08-30 12:06:50 UTC" "2016-08-30 12:08:20 UTC"
#[16] "2016-08-30 12:10:10 UTC" "2016-08-30 12:12:10 UTC" "2016-08-30 12:15:10 UTC" "2016-08-30 12:16:40 UTC" "2016-08-30 12:18:30 UTC"
...