R:用多个时间跨度创建一个时间序列

时间:2017-04-26 12:46:42

标签: r time-series timeserieschart

我的数据如下:

startDate             | endDate              | type
---------------------------
2017-04-11 10:45:06.0 |2017-04-11 10:47:30.0 | Type1
2017-04-11 10:15:01.0 |2017-04-11 11:47:33.0 | Type2
2017-04-11 10:44:09.0 |2017-04-11 10:50:00.0 | Type1
2017-04-11 10:35:06.0 |2017-04-11 10:53:33.0 | Type2

我的目标是在time-series中将其可视化。但据我所知,我需要数据形式的矢量描绘每个时间点的频率。 是否有图书馆或将数据转换为此表单的好方法?或者我是否必须检查每个想要可视化的时间点的条目?

基本上图表应该看起来像这样: (请注意,图像与示例数据不匹配)

enter image description here

1 个答案:

答案 0 :(得分:1)

OP指定他有许多具有给定开始和结束时间的事件,并且他想要描绘 coverage ,即每个时间点的事件数量。

使用 Bioconductor的 foverlaps()包有一个确切的解决方案(参见IRanges vignette中的5.5 计算重叠范围一节)。

但是,Q中的图表表明使用 binning 的解决方案对于OP是可接受的。分箱意味着计算与时间栅格重叠的事件数。这与创建直方图类似,只是特定事件可能跨越多个bin。

data.table包中的Type1函数可用于装箱过程。但首先我们需要准备一些虚拟数据进行演示。

创建虚拟数据

我们创建两种类型的事件。 Type2数量较少但事件较长,set.seed(1L) n1 <- 10L n2 <- n1 * 10L ref_time <- lubridate::ymd_hms("2017-4-26 10:11:12") DT <- rbindlist(list( data.table(t = ref_time + rnorm(n1) * 60 * 60, d = rnorm(n1) * 60 * 60, type = "Type1"), data.table(t = ref_time + rnorm(n2) * 60 * 60, d = rnorm(n2) * 60 * 6, type = "Type2") )) # DT[, c("start", "end") := .(pmin(t, t + d), pmax(t, t + d))] setkey(DT, start, end) # add row numbers DT[, rn := .I] DT # t d type start end rn # 1: 2017-04-26 08:11:50 -64.64035 Type2 2017-04-26 08:10:45 2017-04-26 08:11:50 1 # 2: 2017-04-26 08:22:54 -91.80973 Type2 2017-04-26 08:21:22 2017-04-26 08:22:54 2 # 3: 2017-04-26 08:39:47 -528.21001 Type2 2017-04-26 08:30:58 2017-04-26 08:39:47 3 # 4: 2017-04-26 08:42:57 -13.54830 Type2 2017-04-26 08:42:43 2017-04-26 08:42:57 4 # 5: 2017-04-26 09:21:03 -2236.46609 Type1 2017-04-26 08:43:47 2017-04-26 09:21:03 5 # --- #106: 2017-04-26 11:52:07 183.63903 Type2 2017-04-26 11:52:07 2017-04-26 11:55:11 106 #107: 2017-04-26 11:57:14 899.15817 Type2 2017-04-26 11:57:14 2017-04-26 12:12:13 107 #108: 2017-04-26 12:10:01 -387.06923 Type2 2017-04-26 12:03:34 2017-04-26 12:10:01 108 #109: 2017-04-26 12:21:33 74.71380 Type2 2017-04-26 12:21:33 2017-04-26 12:22:48 109 #110: 2017-04-26 12:35:17 153.03614 Type2 2017-04-26 12:35:17 2017-04-26 12:37:50 110 是较多的较短事件。

library(ggplot2)
ggplot(DT, aes(x = start, y = rn, xend = end, yend = rn, colour = type)) + 
  geom_segment(size = 1) + theme_bw()

最好是可视化:

bin_start_time <- DT[, lubridate::floor_date(min(start), unit = "hour")]
bin_end_time<- DT[, lubridate::ceiling_date(max(end), unit = "hour")]
# time interval can be adjusted 
bin_step <- as.difftime(15L, units = "mins")
bin_cuts <- seq(bin_start_time, bin_end_time, by = bin_step)
bins <- data.table(start = head(bin_cuts, -1L),
                   end   = tail(bin_cuts, -1L),
                   key = "start,end")
# add row numbers
bins[, bn := .I]

head(bins)
#                 start                 end bn
#1: 2017-04-26 08:00:00 2017-04-26 08:15:00  1
#2: 2017-04-26 08:15:00 2017-04-26 08:30:00  2
#3: 2017-04-26 08:30:00 2017-04-26 08:45:00  3
#4: 2017-04-26 08:45:00 2017-04-26 09:00:00  4
#5: 2017-04-26 09:00:00 2017-04-26 09:15:00  5
#6: 2017-04-26 09:15:00 2017-04-26 09:30:00  6

enter image description here

创建用于分组的时间栅格

我们创建一个间隔15分钟的时间栅格

DT

分级

分箱需要使用foverlaps()查找result <- foverlaps(DT, bins)[, .N, by = .(type, start, end)] result[18:24] # type start end N #1: Type1 2017-04-26 11:00:00 2017-04-26 11:15:00 5 #2: Type1 2017-04-26 11:15:00 2017-04-26 11:30:00 4 #3: Type1 2017-04-26 11:30:00 2017-04-26 11:45:00 4 #4: Type1 2017-04-26 11:45:00 2017-04-26 12:00:00 2 #5: Type2 2017-04-26 09:45:00 2017-04-26 10:00:00 14 #6: Type2 2017-04-26 10:00:00 2017-04-26 10:15:00 17 #7: Type2 2017-04-26 10:15:00 2017-04-26 10:30:00 11 中给定的时间栅格中的事件的所有重叠并计算重叠次数。这可以在一个声明中完成:

ggplot(result, aes(start + bin_step/2, N, group = type, colour = type)) + 
  geom_line(size = 1) + expand_limits(y = 0) + theme_bw() 

请注意,频率按类型分别计算。

可视化

geom_step()

enter image description here

此处,数据点位于时间栅格间隔的中间位置。

另一种可能性是ggplot(result, aes(start, N, group = type, colour = type)) + geom_step(size = 1) + expand_limits(y = 0) + theme_bw()

(function() {
    this.init = function () {

    };

    this.runMe = function () {

    };

    this.removeItems = function () {

    };
}).call(myObject.prototype);

enter image description here