在R中,如何将时间戳记间隔数据拆分为常规时隙?

时间:2019-01-02 03:11:22

标签: r

我正在处理描述具有开始和结束时间的事件的数据。例如,它可以采用以下形式:

enter image description here

我想将此数据转换为可以定期计数事件发生次数的形式,以便能够回答从13:15:00到{{1}发生了多少事件的问题。 }和13:29:5913:30:00等。在上面的示例中,仅使用开始时间就可以将第二条记录计入第一个时隙,但是即使集成了结束时间,也不会在第二个规则间隔中将其记录为“进行中”。

要以15分钟的间隔工作,我想出了一个笨拙的解决方案,该解决方案使用13:45:00将数据集“扩展”到tidyr::uncount在24小时内间隔15分钟,然后过滤指定间隔内的数据

24*4=96

这为我提供了所需格式的数据:

enter image description here

但是我感觉必须有一种更聪明的方法来做到这一点。例如,对于非常大的数据集和/或当时间间隔小时(我认为),扩展将不是很好的解决方案。将其扩展为可以工作几天(可能会很痛苦)。

在Stata中,也可以使用library(tidyverse) library(lubridate) library(magrittr) df1 <- tibble::tibble( id = c(1, 2), start_date = c(ymd_hms("2018-12-10 14:45:51", tz = "Australia/Brisbane"), ymd_hms("2018-12-10 13:29:37", tz = "Australia/Brisbane")), end_date = c(ymd_hms("2018-12-10 14:59:04", tz = "Australia/Brisbane"), ymd_hms("2018-12-10 14:02:37", tz = "Australia/Brisbane"))) df2 <- df1 %>% mutate(episode = 96) %>% tidyr::uncount(episode, .id = "sequence") df2$int_start <- rep( seq(ymd_hms("2018-12-10 00:00:00", tz = "Australia/Brisbane"), ymd_hms("2018-12-10 23:59:59", tz = "Australia/Brisbane"), by = "15 mins"), 2) df2$int_end <- df2$int_start + 899 df2 %<>% filter(int_end > start_date & int_start < end_date ) 命令来完成类似的操作。我尝试修改stsplit包中的survSplit,但最终也得到了很多记录:

survival

是否有任何指向实现此类任务的更好方法的指针?

1 个答案:

答案 0 :(得分:2)

您也可以通过将每个start_time视为添加一个活动事件,将每个end_time视为将活动事件减少一个来解决此问题。这种方法使您可以在任何给定的瞬间识别活动事件,并且可以很好地扩展。 (我使用类似的方法来计数数百万个事件,并且基本上是瞬时的。)

BackHandler.exitApp()

enter image description here

如果您还希望定期评估活动计数,则可以将这些时间间隔集成到输出数据框中,如下所示:

df2 <- df1 %>%
  gather(type, time, start_date:end_date) %>%
  mutate(event_chg = if_else(type == "start_date", 1, -1)) %>%
  arrange(time) %>%
  mutate(active_events = cumsum(event_chg))

df2
# A tibble: 4 x 5
#     id type       time                event_chg active_events
#  <dbl> <chr>      <dttm>                  <dbl>         <dbl>
#1     2 start_date 2018-12-10 13:29:37         1             1
#2     2 end_date   2018-12-10 14:02:37        -1             0
#3     1 start_date 2018-12-10 14:45:51         1             1
#4     1 end_date   2018-12-10 14:59:04        -1             0

ggplot(df2, aes(time, active_events)) + geom_step()

然后可以直接绘制这些计数,或者过滤输出数据框以查看它们。在这种情况下,事件ID 1完全在两个15分钟的间隔之间发生。

df2b <- df1 %>%
  gather(type, time, start_date:end_date) %>%
  mutate(event_chg = if_else(type == "start_date", 1, -1)) %>%
  #  NEW SECTION HERE
  bind_rows(data_frame(type = "marker",
               time = seq.POSIXt(ymd_h(2018121013, tz = "Australia/Brisbane"), 
                                 ymd_h(2018121016, tz = "Australia/Brisbane"), 
                                 by  = 15*60), # 15 minutes of seconds = 15*60
               event_chg = 0)) %>% 
  #  END OF NEW SECTION
  arrange(time) %>%
  mutate(active_events = cumsum(event_chg))

enter image description here