涉及POSIX的逐步或累积时间序列

时间:2019-02-11 17:16:29

标签: r datatable posix purrr self-reference

我有一个带有两个变量timedif的数据框,

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

我在(iterative cumsum where sum determines the next position to be added)之前曾问过类似的问题,但是那里的非循环解决方案涉及accumulate()Reduce(),它们似乎不适用于POSIXct对象。至少它们产生以下错误binary '+' is not defined for "POSIXt" objects

有人知道怎么得到这个吗?

1 个答案:

答案 0 :(得分:0)

我同意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

如果您有很多数据,也许最好预先分配和/或增加行索引的单独向量,而不是修改原始数据中的新列,但我希望这会有所帮助。