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



我有几个地点的一些商业活动的开始和结束时间。活动可能会也可能不会在每一天发生,并且活动持续时间不重叠。例如,运行以下命令:

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,每行对应一对location和sharp hour(例如,as.POSIXct("2010/1/1 13:00:00")),其中indicator是一个伪值,如果这个小时介于该位置的一些事件开始和结束时间之间,则为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到2010/1/1下午13:25之间有一个事件。所以早上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

然后我从那里得到每个位置每小时的正确指标。不过,我不知道如何将开始/结束时间转换为每小时的观测值。

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

话虽如此,但我没有解决方案,我想寻求帮助。

此外,我想要的只是具有三列的输出。在贡献时,请不要被我的想法所束缚,这可能是无效的。

值得一提的是,实际问题涉及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))

最新更新