[R] extending zoo (or ts) objects

Gabor Grothendieck
2007-10-20T14:14:55Z

On 10/20/07, Felix Andrews <felix at nfrac.org>
wrote:
> list(...)
>
> I would like to extend zoo objects for use in a hydrological
> application. By that I mean I want to attach various attributes, such
> as id numbers, coordinates of the observation location, a units
> specification, etc. I might also want to add to the "class"
attribute
> (inheriting from "zoo") and define some custom methods. I can add
> attributes() to a zoo object, but the problem is that when I do
> operations on the object, such as window, `[`, lag etc, the attributes
> are lost. That makes it awkward to manage.
>
> E.g.
> > foo <- zoo(1:5, order.by=as.Date(1:5))
> > attr(foo, "location") <- c(150, -35)
>
> The functions below all return a modified zoo object; test which ones
> keep the user-specified attributes:
>
> > attr(foo[1:4], "location")
> NULL
> > attr(window(foo), "location")
> NULL
> > attr(lag(foo), "location")
> NULL
> > attr(na.approx(foo), "location") ## this one keeps
attributes
> [1] 150 -35
> > attr(rollmean(foo, 1), "location")
> NULL
> > attr(aggregate(foo, months, mean), "location")
> NULL
>
> I notice that many operations on ts objects have the same behaviour
> (dropping user-specified attributes). In contrast, subsetting
> (indexing) a data.frame keeps them, as I had expected.

Yes, in general zoo was modelled on ts, not on data.frame; however, I
will add this to the wish list (see WISHLIST file in the package).

You could define a zoo2 class that is a subclass of zoo to do it like
this where below we have shown a constructor function zoo2 and a method
for [.zoo2.  You can provide other zoo2 methods similarly if you need them:

"[.zoo2" <- function(x, ...) {
	class(x) <- setdiff(class(x), "zoo2")
	y <- NextMethod()
	attributes(y) <- modifyList(attributes(x), attributes(y))
	class(y) <- c("zoo2", class(y))
	y
}

zoo2 <- function(x, ...) {
	y <- zoo(x, ...)
	class(y) <- unique(c("zoo2", class(y)))
	y
}

# test
library(zoo)
z <- zoo2(matrix(1:24, as.Date(1:6))
attr(z, "abc") <- 3
z[, 2:3]