如何在保持日期间隔和其他值的同时将数据从5分钟汇总到30分钟

时间:2013-12-09 20:20:48

标签: r aggregate zoo

我有以下数据:

value <- c(1.869, 1.855, 1.855, 1.855, 1.855, 1.855, 1.855, 1.848, 1.848, 1.848, 1.848, 1.848, 1.848, 1.849)
date <- c("2013-08-28 08:00:00 UTC", "2013-08-28 08:05:00 UTC", "2013-08-28 08:10:00 UTC", "2013-08-28 08:15:00 UTC", "2013-08-28 08:20:00 UTC", "2013-08-28 08:25:00 UTC", "2013-08-28 08:30:00 UTC", "2013-08-28 08:35:00 UTC", "2013-08-28 08:40:00 UTC", "2013-08-28 08:45:00 UTC", "2013-08-28 08:50:00 UTC", "2013-08-28 08:55:00 UTC", "2013-08-28 09:00:00 UTC", "2013-08-28 09:05:00 UTC")
indicator <- c(1,0,0,1,0,0,0,0,0,0,0,0,0,1)

data <- data.frame(date=date,value=value, indicator=indicator)

我想做两件事。首先,我希望将其汇总/加总到30分钟,但结束于:00和:30。例如,此数据中的第一个值不会包含在计算中,但8:05到8:30将汇总到8:30,8:35到9:00到9:00,依此类推。我还想汇总指标值。所以,如果有一个存在,我希望有一个1(我猜总和也可以工作,因为它不是零)。

我已经尝试过rollapply(但我必须手动确保数据从8:05开始)来自动物园包,但是想保留日期并聚合指标:

aggdata <- rollapply(data=data$value,width=6,FUN=sum,by=6)

不包括整整30分钟间隔的数据对我来说毫无用处,所以我宁愿不包含这些数据。我想要的输出是:

date                       value  indicator
"2013-08-28 08:00:00 UTC"  1.869  1
"2013-08-28 08:30:00 UTC"  11.13  1
"2013-08-28 09:00:00 UTC"  11.088 0 
"2013-08-28 09:05:00 UTC"  1.849  1

或更好:

date                       value  indicator
"2013-08-28 08:00:00 UTC"  NA     NA
"2013-08-28 08:30:00 UTC"  11.13  1
"2013-08-28 09:00:00 UTC"  11.088 0 
"2013-08-28 09:05:00 UTC"  NA     NA

甚至更好:

date                       value  indicator
"2013-08-28 08:30:00 UTC"  11.13  1
"2013-08-28 09:00:00 UTC"  11.088 0 

3 个答案:

答案 0 :(得分:3)

这似乎也是正确的:

data$date <- as.POSIXct(as.character(data$date))

interval <- seq(min(data$date), max(data$date), "30 mins")

intervals <- c(data$date[1], interval + 5*60)

res <- na.omit(aggregate(list(value = data$value, indicator = data$indicator), 
                                list(date = findInterval(data$date, intervals)), 
                                      function(x) if(length(x) == 6) sum(x) else NA))

res$date <- interval[res$date]

res
#                 date  value indicator
#2 2013-08-28 08:30:00 11.130         1
#3 2013-08-28 09:00:00 11.088         0

答案 1 :(得分:2)

那应该做的工作

## convert from string to date (POSIX)
dt <- strptime(data$date,format="%Y-%m-%d %H:%M:%S")
## create bins to collect the right periods
##  1) subtract the modulo to 30min (-> 30 min bins)
##  2) add 30 if this modulo is not 0 (-> they and at :00 or :30)
bins <- strftime(as.POSIXct(dt+60*(-(dt$min %% 30)
                                   + ifelse(dt$min %% 30,30,0)),
                            origin="1970-01-01"),'%Y-%m-%d %H:%M')
## use this bins
data.frame(value=tapply(data$value,bins,sum),
           indicator=tapply(data$indicator,bins,
             function(x) ifelse(sum(x),1,0)))

答案 2 :(得分:1)

> z <- read.zoo(data, FUN = identity)
> zr <- rollapplyr(z[-1, ], 6, sum, by = 6)
> zr
                         value indicator
2013-08-28 08:30:00 UTC 11.130         1
2013-08-28 09:00:00 UTC 11.088         0

虽然最好将它留在动物园中以将其转换回数据框使用:fortify.zoo

library(ggplot2)
fortify(zr)