R 中的时间序列 - 重塑?

Time Series in R - reshape?

我正在尝试分析从 Outlook 导出的 .ics 文件。 该文件的结构在以下最小示例数据集中给出

d1 <- structure(list(start = structure(1:3, .Label = c("01.01.2014 09:00",  "01.01.2014 18:00", "02.01.2014 08:00"), class = "factor"), end = structure(1:3, .Label = c("01.01.2014 17:00",  "01.01.2014 19:00", "02.01.2014 11:00"), class = "factor"), sth = structure(1:3, .Label = c("A",  "B", "C"), class = "factor")), .Names = c("start", "end", "sth" ), class = "data.frame", row.names = c(NA, -3L))

但实际上我需要以下结构中的数据

d2 <- structure(list(time = structure(1:27, .Label = c("01.01.2014 09:00",  "01.01.2014 10:00", "01.01.2014 11:00", "01.01.2014 12:00", "01.01.2014 13:00",  "01.01.2014 14:00", "01.01.2014 15:00", "01.01.2014 16:00", "01.01.2014 17:00",  "01.01.2014 18:00", "01.01.2014 19:00", "01.01.2014 20:00", "01.01.2014 21:00",  "01.01.2014 22:00", "01.01.2014 23:00", "02.01.2014 00:00", "02.01.2014 01:00",  "02.01.2014 02:00", "02.01.2014 03:00", "02.01.2014 04:00", "02.01.2014 05:00",  "02.01.2014 06:00", "02.01.2014 07:00", "02.01.2014 08:00", "02.01.2014 09:00",  "02.01.2014 10:00", "02.01.2014 11:00"), class = "factor"), sth = structure(c(2L,  2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 4L), .Label = c("", "A",  "B", "C"), class = "factor")), .Names = c("time", "sth"), class = "data.frame", row.names = c(NA,  -27L))

言下之意: d1 由某事(某事)的开始和结束时间组成。 我需要 "complete" 系列结构 (d2) 中的数据,其中根据 d1 中事件 (sth) 的持续时间填充连续元素。

我尝试尝试合并和长与宽...但我无法完成这项工作...

我希望我能够解释我的问题... 感谢您的任何提示!

我们可以使用 data.table。将 'data.frame' 转换为 'data.table' (setDT(d1)),将 'start' 和 'end' 转换为 POSIXct class,通过获取 [= 'start' 和 'end' 列的 14=] 按 'sth' 分组,与 'time' 的第一个和最后一个观察值的 seq 连接,并更改 NA 元素到 ''

library(data.table)
res <- setkey(setDT(d1)[, 1:2 := lapply(.SD, as.POSIXct,
        format='%d.%m.%Y %H:%M'), .SDcols=1:2][,list(time=seq(start, end,
        by='hour')) ,sth], time)[J(seq(time[1L], time[.N], by='hour'))][
        is.na(sth), sth:='']

如果 'time' 需要采用与 'd2' 相同的格式,但我会将其保留在 'datetime' POSIXct class.

res[, time:= format(time, '%d.%m.%Y %H:%M')]
#   sth             time
# 1:   A 01.01.2014 09:00
# 2:   A 01.01.2014 10:00
# 3:   A 01.01.2014 11:00
# 4:   A 01.01.2014 12:00
# 5:   A 01.01.2014 13:00
# 6:   A 01.01.2014 14:00
# 7:   A 01.01.2014 15:00
# 8:   A 01.01.2014 16:00
# 9:   A 01.01.2014 17:00
#10:   B 01.01.2014 18:00
#11:   B 01.01.2014 19:00
#12:     01.01.2014 20:00
#13:     01.01.2014 21:00
#14:     01.01.2014 22:00
#15:     01.01.2014 23:00
#16:     02.01.2014 00:00
#17:     02.01.2014 01:00
#18:     02.01.2014 02:00
#19:     02.01.2014 03:00
#20:     02.01.2014 04:00
#21:     02.01.2014 05:00
#22:     02.01.2014 06:00
#23:     02.01.2014 07:00
#24:   C 02.01.2014 08:00
#25:   C 02.01.2014 09:00
#26:   C 02.01.2014 10:00
#27:   C 02.01.2014 11:00
# sth             time

非常感谢@akrun!你让我今天一整天都感觉很好! 我想我现在有了自己的解决方案,虽然不是很漂亮,但对我有用!

library(data.table)
t1 <- setDT(d1)[,  seq(from=as.POSIXct(start, format='%d.%m.%Y %H:%M'), to=as.POSIXct(end, format='%d.%m.%Y %H:%M'), by='hour'), sth]
t2 <- seq(t1$V1[1], t1$V1[nrow(t1)], by="hour")
t1 <- as.data.frame(t1)
t2 <- data.frame(t2)
names(t2) <- "time"
names(t1) <- c("sth", "time")
merge(t2, t1, by="time", all=T)

非常感谢!