How to split a date and time object in a zoo for aggregation

I imported data with a five-minute interval into the zoo object, where the index is a cron with date and time:

 > d
 (09/09/09 16:45:10) 13.2 5.8
 (09/09/09 16:50:10) 8.3 0.7
 (09/09/09 16:55:10) 4.7 0.7
 (09/09/09 17:00:10) 6.6 0.7
 (09/09/09 17:05:10) 4.6 0.7

I am trying to aggregate by quarterly hours.

I found a way to do this by returning to the line, but the output is no longer a zoo.

 > r = data.frame (aggregate (d, trunc (chron (times = substr (as.character (index (d)), 11,18)), "00:15:00"), mean)
 > r
 00:00:00 0.5644444
 00:15:00 0.5400000
 00:30:00 0.5488889
 00:45:00 0.6155556
 01:00:00 0.3422222

While I can do this, I tried to do this initially. I found that a combination with a zoo can do day and hour, but I could not separate this hour.

+1
r
source share
3 answers

Given Shane’s idea, I changed it a little ... The initial question was how to aggregate in minutes and get rid of the date. Also, since math didn't like midnight before, I use string parsing.

 # Where X is a zoo obj with chron timestamps containing both time & date
 # and min is like "00:30:00" for half hour intervals
 > trunc.chrontime = function (x, min)
   {
     if (! inherits (x, "times")) 
         x = as.chron (x)
     s = substr (as.character (x), 11.18)
     c = chron (times = s)
     trunc (c, min)
   }

 > s = aggregate (d, trunc.minstr (index (d), "00:30:00"), mean)
 s
 00:00:00 0.5522222 0.4988889 0.006666667
 00:30:00 0.5822222 0.5366667 0.012222222
 01:00:00 0.3388889 0.4455556 0.000000000
 01:30:00 0.3422222 0.4344444 0.000000000
 02:00:00 0.3366667 0.4366667 0.000000000 ...
+1
source share

I do not believe that there is a way to do this, built into the zoo or cron, but you can create your own function using a little math. Here you are:

trunc.minutes <- function (x, n.minutes) { if (!inherits(x, "times")) x <- as.chron(x) x <- as.numeric(x) sec <- round(24 * 3600 * abs(x - floor(x))) h <- (sec%/%(n.minutes*60))/(60/n.minutes) hour <- as.integer(h) minutes <- (h %% hour) * 60 chron(dates=chron::dates(x), times=times(paste(hour, minutes, "00", sep=":"))) } 

Here is a usage example:

 dts <- chron::dates(c("02/27/92", "02/27/92", "01/14/92", "02/28/92", "02/01/92")) tms <- times(c("23:03:20", "23:29:56", "01:03:30", "18:21:03", "16:56:26")) x <- chron(dates = dts, times = tms) # original dates x [1] (02/27/92 23:03:20) (02/27/92 22:29:56) (01/14/92 01:03:30) [4] (02/28/92 18:21:03) (02/01/92 16:56:26) trunc.minutes(x, 15) # new dates at 15 minute intervals [1] (02/27/92 23:00:00) (02/27/92 22:15:00) (01/14/92 01:00:00) [4] (02/28/92 18:15:00) (02/01/92 16:45:00) trunc.minutes(x, 30) # new dates at 30 minute intervals [1] (02/27/92 23:00:00) (02/27/92 22:00:00) (01/14/92 01:00:00) [4] (02/28/92 18:00:00) (02/01/92 16:30:00) 

Finally, you can now use this function to aggregate data:

 ts.zoo <- zoo(rnorm(5), x) # a zoo time series 

Or simply use these new dates for aggregation (see how it updates the second example, since there are two values ​​in this window):

 > aggregate(ts.zoo, trunc.minutes(x, 15), mean) (01/14/92 01:00:00) (02/01/92 16:45:00) (02/27/92 23:00:00) (02/27/92 23:15:00) -0.6738659 -0.4844803 0.7968155 -1.3571121 (02/28/92 18:15:00) 0.7625861 > aggregate(ts.zoo, trunc.minutes(x, 30), mean) (01/14/92 01:00:00) (02/01/92 16:30:00) (02/27/92 23:00:00) (02/28/92 18:00:00) -0.6738659 -0.4844803 -0.2801483 0.7625861 
+4
source share

chron has a trunc.times method, so we can do this:

 library(zoo) library(chron) z <- zoo(1:5, chron(c("02/27/92", "02/27/92", "01/14/92", "02/28/92", "02/01/92"), c("23:03:20", "23:29:56", "01:03:30", "18:21:03", "16:56:26"))) aggregate(z, function(x) trunc(x, "00:15:00"), mean) 
+2
source share

All Articles