R时间聚合与开始/停止

时间:2015-10-27 15:34:06

标签: r aggregate

我有一组具有开始和停止时间的时间序列数据。每个事件可以持续几秒到几天,我需要计算总和,在这个例子中,使用的总内存,当时活动的每小时。以下是数据样本:

mem_used    start_time            stop_time 
16          2015-10-24 17:24:41   2015-10-25 04:19:44   
80          2015-10-24 17:24:51   2015-10-25 03:14:59   
44          2015-10-24 17:25:27   2015-10-25 01:16:10   
28          2015-10-24 17:25:43   2015-10-25 00:00:31   
72          2015-10-24 17:30:23   2015-10-24 23:58:31   

在这种情况下,它应该给出类似的东西:

time                  total_mem
2015-10-24 17:00:00   240
2015-10-24 18:00:00   240
...
2015-10-25 00:00:00   168
2015-10-25 01:00:00   140
2015-10-25 02:00:00   96
2015-10-25 03:00:00   96
2015-10-25 04:00:00   16

我试图用聚合函数做一些事情,但我无法弄明白。有任何想法吗?感谢。

2 个答案:

答案 0 :(得分:1)

以下是我如何使用lubridate进行操作的方法。

首先,请确保您的日期为POSIXct格式:

dat$start_time = as.POSIXct(dat$start_time, format = "%Y-%m-%d %H:%M:%S")
dat$stop_time = as.POSIXct(dat$stop_time, format = "%Y-%m-%d %H:%M:%S")

然后使用lubridate制作一个间隔对象:

library(lubridate)
dat$interval <- interval(dat$start_time, dat$stop_time)

现在我们可以制作一个时间向量,用你想要的时间替换它们:

z <- seq(start = dat$start_time[1], stop = dat$stop_time[5], by = "hours")

总结那些重叠的地方:

out <- data.frame(times = z,
                  mem_used = sapply(z, function(x) sum(dat$mem_used[x %within% dat$interval]))) 

                times mem_used
1 2015-10-24 17:24:41       16
2 2015-10-24 18:24:41      240
3 2015-10-24 19:24:41      240
4 2015-10-24 20:24:41      240
5 2015-10-24 21:24:41      240
6 2015-10-24 22:24:41      240
7 2015-10-24 23:24:41      240

以下是使用的数据:

structure(list(mem_used = c(16L, 80L, 44L, 28L, 72L), start_time = structure(c(1445721881, 
1445721891, 1445721927, 1445721943, 1445722223), class = c("POSIXct", 
"POSIXt"), tzone = ""), stop_time = structure(c(1445761184, 1445757299, 
1445750170, 1445745631, 1445745511), class = c("POSIXct", "POSIXt"
), tzone = "")), .Names = c("mem_used", "start_time", "stop_time"
), row.names = c(NA, -5L), class = "data.frame")

答案 1 :(得分:0)

以下是基于dplyrlubridate的其他解决方案。 确保首先获得正确格式的数据(例如POSIXct中的日期)

library(dplyr)
library(lubridate)

glimpse(df)
## Observations: 5
## Variables: 3
## $ mem_used   (int) 16, 80, 44, 28, 72
## $ start_time (time) 2015-10-24 17:24:41, 2015-10-24 17:24:51...
## $ end_time   (time) 2015-10-25 04:19:44, 2015-10-25 03:14:59...

然后我们将保留小时(删除分钟和秒),因为我们希望每小时聚合一次。

### Remove minutes and seconds
minute(df$start_time) <- 0
second(df$start_time) <- 0
minute(df$end_time) <- 0
second(df$end_time) <- 0

现在最重要的一步是在data.framestart_time之间的每小时创建一个新行end_time。例如,如果在原始data.frame的第一行,我们在start_timeend_time之间有5个小时,我们将以5行结束,值mem_used重复5次

###
n <- nrow(df)
l <- lapply(1:n, function(i) {
  date <- seq.POSIXt(df$start_time[i], df$end_time[i], by = "hour")
  mem_used <- rep(df$mem_used[i], length(date))
  data.frame(time = date, mem_used = mem_used)
})


df <- Reduce(rbind, l)
glimpse(df)
## Observations: 47
## Variables: 2
## $ time     (time) 2015-10-24 17:00:00, 2015-10-24 18:00:00, ...
## $ mem_used (int) 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,...

最后,我们现在可以使用dplyraggregate(或其他类似功能)汇总

df %>%
  group_by(time) %>%
  summarise(tot = sum(mem_used))
##                   time   tot
##                 (time) (int)
## 1  2015-10-24 17:00:00   240
## 2  2015-10-24 18:00:00   240
## 3  2015-10-24 19:00:00   240
## 4  2015-10-24 20:00:00   240
## 5  2015-10-24 21:00:00   240
## 6  2015-10-24 22:00:00   240
## 7  2015-10-24 23:00:00   240
## 8  2015-10-25 00:00:00   168
## 9  2015-10-25 01:00:00   140
## 10 2015-10-25 02:00:00    96
## 11 2015-10-25 03:00:00    96
## 12 2015-10-25 04:00:00    16

## Or aggregate
aggregate(mem_used ~ time, FUN = sum, data = df)