ступенчатый или накопительный временной ряд с участием POSIX - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть кадр данных с двумя переменными, time и dif,

library(lubridate)
a <- data.frame(time=seq(from=as.POSIXct("2019-01-01 01:01:00"),to=as.POSIXct("2019-01-01 01:15:00"),by="min"),dif=make_difftime(mins=c(2,3,5,5,5,2,6,6,6,6,6,6,4,4,4)))

> a
                  time    dif
1  2019-01-01 01:01:00 2 mins
2  2019-01-01 01:02:00 3 mins
3  2019-01-01 01:03:00 5 mins
4  2019-01-01 01:04:00 5 mins
5  2019-01-01 01:05:00 5 mins
6  2019-01-01 01:06:00 2 mins
7  2019-01-01 01:07:00 6 mins
8  2019-01-01 01:08:00 6 mins
9  2019-01-01 01:09:00 6 mins
10 2019-01-01 01:10:00 6 mins
11 2019-01-01 01:11:00 6 mins
12 2019-01-01 01:12:00 6 mins
13 2019-01-01 01:13:00 4 mins
14 2019-01-01 01:14:00 4 mins
15 2019-01-01 01:15:00 4 mins

, и я хотел бы получить последовательность, которая начинается с 01:01:00, добавляет значение difи затем продолжается на 01:01:00 + 2 mins = 01:03:00, затем добавляет значение dif и продолжается на 01:03:00 + 5 mins = 01:08:00 и так далее.Таким образом, желаемый результат равен

                  time    dif
1  2019-01-01 01:01:00 2 mins
3  2019-01-01 01:03:00 5 mins
8  2019-01-01 01:08:00 6 mins
14 2019-01-01 01:14:00 4 mins

Я уже задавал подобный вопрос раньше ( итеративное cumum, где sum определяет следующую позицию, которая будет добавлена ​​), но решения без петель там включают accumulate() и Reduce(), которые, кажется, не работают с объектами POSIXct.По крайней мере, они выдают следующую ошибку binary '+' is not defined for "POSIXt" objects.

Кто-нибудь знает, как это получить?

1 Ответ

0 голосов
/ 12 февраля 2019

Я согласен с digEmAll, что цикл, вероятно, будет более ясным решением, чем любое умное решение без цикла, о котором я сейчас могу думать.

Вот подход, который пытается минимизировать повторяющийся линейный поиск или ростструктуры данных, сначала вычисляя карту, которая соединяет каждую строку с той, которая следует, выполняя объединение.

a$row <- 1:nrow(a)
b <- data.frame(time_to = a$time + a$dif)
row_map <- merge(a, b, by.x = "time", by.y = "time_to", all.y = TRUE)$row

a$in_output <- FALSE
current_row <- 1

while(!is.na(current_row)) {
  a[current_row, "in_output"] <- TRUE
  current_row <- row_map[[current_row]]
}

a[a$in_output, c("time", "dif")]

                  time    dif
1  2019-01-01 01:01:00 2 mins
3  2019-01-01 01:03:00 5 mins
8  2019-01-01 01:08:00 6 mins
14 2019-01-01 01:14:00 4 mins

Если у вас много данных, возможно, было бы лучше предварительно выделить и /или увеличьте отдельный вектор индексов строк вместо изменения нового столбца в исходных данных, но я надеюсь, что это поможет.

...