2013-12-09 86 views
2

,我有以下数据:如何从5分钟汇总数据,到30分钟,同时保持日期的时间间隔等数值

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个礼物,我希望那里有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 

回答

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) 
+0

我喜欢这个答案除了'Z [-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))) 
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

要聚合8:05至8:30和报告(即汇总间隔结束时的汇报时间),并忽略没有6次观察的任何30分钟间隔,请使用以下内容:

data$date <- as.POSIXct(data$date) 
data$date.30min <- as.POSIXct(ceiling(as.numeric(data$date)/(30 * 60)) * 
    (30 * 60), origin='1970-01-01') 
sumif6 <- function(x) { 
    if(length(x) == 6) sum(x) else NA 
} 
res30 <- na.omit(aggregate(cbind(value, indicator) ~ date.30min, data, sumif6)) 
res30 
#   date.30min value indicator 
#2 2013-08-28 08:30:00 11.130   1 
#3 2013-08-28 09:00:00 11.088   0 

如果您需要聚合8:00到8:25,并报告说,8点(即,在汇聚间隔的开始报告倍),只需使用floor(),而不是上限:

data$date.30min <- as.POSIXct(floor(as.numeric(data$date)/(30 * 60)) * 
    (30 * 60), origin='1970-01-01') 

如果您需要15分钟,而不是30聚集,只需用15小号取代30 S,并创建一个新sumif3功能:

data$date.15min <- as.POSIXct(floor(as.numeric(data$date)/(15 * 60)) * 
    (15 * 60), origin='1970-01-01') 
sumif3 <- function(x) { 
    if(length(x) == 3) sum(x) else NA 
} 
res15 <- na.omit(aggregate(cbind(value, indicator) ~ date.15min, data, sumif3))