Question

I would like to calculate mean for each row for this zoo object, so at the end I need to have a new zoo object with mean for each minute. Actually I am trying to apply more advanced statistics but from the computational point of view, it should be the same as mean.

head(zs)

2014-03-09 08:00:00 1839.00 1842.00 1849.00 1838.50 1851.75 1843.50 1862.50 1874.00 1875.00 1878.00
2014-03-09 08:01:00 1838.75 1842.00 1848.75 1838.25 1851.75 1844.25 1862.50 1874.00 1875.25 1877.75
2014-03-09 08:02:00 1838.50 1842.25 1848.25 1838.25 1851.50 1843.75 1862.50 1874.00 1875.50 1878.00
2014-03-09 08:03:00 1839.25 1842.50 1848.25 1838.50 1851.50 1843.00 1862.25 1874.00 1875.50 1877.75
2014-03-09 08:04:00 1839.25 1842.50 1848.25 1838.00 1851.50 1843.00 1862.25 1874.25 1875.25 1877.75
2014-03-09 08:05:00 1838.75 1842.25 1848.25 1837.75 1851.75 1843.50 1862.25 1874.00 1875.50 1877.75
Was it helpful?

Solution

Try this:

zoo(rowMeans(zs), time(zs))

or

zoo(apply(zs, 1, mean), time(zs))

or

Reduce(`+`, as.list(zs)) / ncol(zs)

or

zmean <- zs[, 1]
for(i in 2:ncol(zs)) zmean <- zmean + zs[, i]
zmean <- zmean / ncol(zs)

ADDED a few more approaches

OTHER TIPS

I ran into this problem and wanted a more robust solution. Specifically, I wanted a function that worked identically to apply except when a zoo object (or object that inherits from zoo, such as xts) was passed in the argument X. In this case, the function should return a zoo (or xts etc.) object whenever possible. The result should also retain any additional attributes that the user may have attached to the original zoo object.

There are several challenges. First, depending on what's passed to apply via the arguments MARGIN and FUN, apply might return a list, a vector, or an array with dimensions greater than 2. See the apply documentation for more details.

So, if you think about it, the only time result from apply can be returned as a zoo object is if the result is either a matrix with nrow(result) == nrow(originalZooObject) or a vector with length(result) == nrow(originalZooObject). Otherwise, you can't be sure how to add the index values of the original zoo object to the result from apply.

I came up with the following code which retains all of the applicable attributes of the original zoo object in the result. Therefore, it will also work with most S3 classes built atop zoo, for instance, xts.

The only thing I am aware of that won't work well is that the user may have attached an attribute that applies to the columns of the original zoo object. If FUN consolidates columns, then the user attribute might not be appropriate for the columns of the result.

Although I used the naming convention for dispatch from a generic function, apply is not a generic, so apply.zoo is designed to be called directly. If one were to override the apply function with generic version of apply, then apply.zoo would run automatically any time a zoo object were passed to apply.

apply.zoo = function(X, MARGIN, FUN, ...) {
  result = apply(as.matrix(X), MARGIN, FUN, ...)
  # if result is not a list and X is a zoo object, we can try to convert result
  # to zoo.
  if(!is.list(result) | is.zoo(X)) {
    # if FUN was applied across rows and has the right length but simplfied to a
    # vector, convert result back to a matrix
    if(is.null(dim(result)) & MARGIN[1] == 1 & length(result) == nrow(X)) {
      result = matrix(result, ncol = 1, dimnames = list(NULL, "result"))
    }
    # if we don't have a matrix at this point, we can't convert back to a zoo object.
    if(is.matrix(result)) {
      # the matrix returned by apply sometimes has dates as columns and series as
      # rows.  Check for this and transpose.
      if(identical(dimnames(result)[[1]], dimnames(X)[[2]])) result = t(result)
      # if result has maintained the same number of rows, it can be restored to a
      # zoo object.
      if(identical(nrow(X), nrow(result))){
        # first ensure the dimname of rows is NULL
        dimnames(result)[1] = list(NULL)
        # then restore all attributes, other than dim and dimnames
        result = 
          do.call(
            structure, 
            c(
              list(result), 
              attributes(X)[-which(names(attributes(X)) %in% c("dim", "dimnames"))]
            )
          )

      }
    }
  }
  result
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top