给定开始和结束时间,创建每小时标签以指示一个小时是否在持续时间内

Given start and end times, create hourly labels to indicate whether an hour is in the duration or not

我有几个地点的一些商业活动的开始和结束时间。该事件可能每天都发生,也可能不发生,并且事件持续时间不重叠。例如,运行 这个:

inputdata = data.frame(
        location = c('x','x','y','z','z'),
        start = c(as.POSIXct("2010/1/1 8:28:00"),as.POSIXct("2010/1/2 7:20:00"),
                  as.POSIXct("2010/1/1 10:22:00"),
                  as.POSIXct("2010/1/5 13:28:00"),as.POSIXct("2010/1/7 15:39:00")),
        end = c(as.POSIXct("2010/1/1 13:25:00"),as.POSIXct("2010/1/2 10:09:00"),
                as.POSIXct("2010/1/1 15:24:00"),
                as.POSIXct("2010/1/6 00:28:00"),as.POSIXct("2010/1/7 19:34:00"))
)

输入数据如下:

  location               start                 end
1        x 2010-01-01 08:28:00 2010-01-01 13:25:00
2        x 2010-01-02 07:20:00 2010-01-02 10:09:00
3        y 2010-01-01 10:22:00 2010-01-01 15:24:00
4        z 2010-01-05 13:28:00 2010-01-06 00:28:00
5        z 2010-01-07 15:39:00 2010-01-07 19:34:00

我想构建一个包含三列的每小时数据集:1.location、2.hour 和 3.indicator,每行代表一对位置和整点(例如, as.POSIXct("2010/1/1 13:00:00")) 其中指示器是虚拟的,=1 如果这个小时在该位置的某些事件开始和结束时间之间。 例如,假设输出的每小时数据为 2010-01-01 到 2010-01-07。 运行 这个:

output = data.frame(
location = rep(c('x','y','z'),
each=length(seq(as.POSIXct("2010/1/1"), as.POSIXct("2010/1/7 23:00:00"), "hours"))),
hour = rep(seq(as.POSIXct("2010/1/1"), as.POSIXct("2010/1/7 23:00:00"), "hours"),3),
indicator = rep(0,3*length(seq(as.POSIXct("2010/1/1"), as.POSIXct("2010/1/7 23:00:00"), "hours"))))

所以我们得到前六行如下所示:

  location                hour indicator
1        x 2010-01-01 00:00:00         0
2        x 2010-01-01 01:00:00         0
3        x 2010-01-01 02:00:00         0
4        x 2010-01-01 03:00:00         0
5        x 2010-01-01 04:00:00         0
6        x 2010-01-01 05:00:00         0

现在,如果同一行的小时有一个对同一行的位置有效的事件,我们需要将指示器的值更改为 1。 例如,由于位置 x 在 2010/1/1 的 8:28 am 和 2010/1/1 的 13:25 pm 之间有一个事件。所以早上 7 点到下午 14 点的行应该是这样的:

  location                hour indicator
8        x 2010-01-01 07:00:00         0
9        x 2010-01-01 08:00:00         1
10       x 2010-01-01 09:00:00         1
11       x 2010-01-01 10:00:00         1
12       x 2010-01-01 11:00:00         1
13       x 2010-01-01 12:00:00         1
14       x 2010-01-01 13:00:00         1
15       x 2010-01-01 14:00:00         0

我似乎可以详尽地搜索每一对位置和时间,并更新指示器的值是该位置某个事件的开始和结束时间之间的时间。但我怀疑这是最好的方法。

或者我在想我可以先将输入数据转换为小时数据,只有在开始和结束时间之间才会有小时。换句话说,转换后的数据应该是这样的:

 location                hour indicator
1       x 2010-01-01 08:00:00         1
2       x 2010-01-01 09:00:00         1
3       x 2010-01-01 10:00:00         1
4       x 2010-01-01 11:00:00         1
5       x 2010-01-01 12:00:00         1
6       x 2010-01-01 13:00:00         1
7       x 2010-01-02 07:00:00         1
8       x 2010-01-02 08:00:00         1
9       x 2010-01-02 09:00:00         1
10      x 2010-01-02 10:00:00         1
11      y 2010-01-01 10:00:00         1
12      y 2010-01-01 11:00:00         1

然后我从那里去获取每个位置每小时的正确指标。虽然,我不知道如何将 start/end 小时转换为每小时观察值。

到目前为止,这是我对这个问题的全部了解。

说到这里,我没有解决办法,想寻求帮助。

此外,我只想要三列的输出。投稿时,请不要拘泥于我的思路,效率可能不高

值得一提的是,实际问题涵盖5年,有30个地点。所以算法需要高效。

这是一种使用交叉连接执行此操作的方法。

library(dplyr)

hours = 
  data_frame(hour = seq(as.POSIXct("2010/1/1"), 
                        as.POSIXct("2010/1/7 23:00:00"), 
                        "hours") ) %>%
  merge(inputdata %>% select(location) %>% distinct) 

hours %>%
  left_join(inputdata) %>%
  filter(start <= hour & hour <= end) %>%
  right_join(hours) %>%
  mutate(indicator = +!is.na(start))