sdgfsdh
sdgfsdh

Reputation: 37121

In R, how do I maintain column names through by and zoo?

I have a long-format data.frame which I would like to use to construct a wide-format zoo series.

The data.frame looks like:

        Date Label Value
1 2015-03-21     A     1
2 2015-03-22     B     6
3 2015-03-22     A     2
4 2015-03-23     A     7
5 2015-03-23     B     5
...

For example:

d <- data.frame(
    Date = c(Sys.Date() - 2, Sys.Date() - 1, Sys.Date() -1, Sys.Date(), Sys.Date()), 
    Label = c("A", "B", "A", "A", "B"), 
    Value = c(1, 6, 2, 7, 5))

My result should be a zoo that looks like:

           A  B ...
2015-03-21 1 NA ...
2015-03-22 2  6 ...
2015-03-23 7  5 ...
...

I have managed to achieve this using:

f <- function(x) {

    zoo(x$Value, order.by = x$Date)
}

do.call(merge.zoo, by(d, factor(d$Label), f))

where d is the data.frame.

However, when d only contains one Label, it drops the column name somewhere:

2015-03-21 2015-03-22 2015-03-23 
         1          2          7

and names(d) gives NULL.

How can I maintain the column names, even when the output zoo is univariate?

Upvotes: 1

Views: 706

Answers (2)

sdgfsdh
sdgfsdh

Reputation: 37121

The problem is that merge.zoo will drop names for a univariate zoo by default.

This behaviour can be overridden by passing drop = F to the args list. We can use a partial function application of merge.zoo to achieve this when using do.call:

f <- function(x) {

    zoo(x$Value, order.by = x$Date)
}

s <- do.call(partial(merge.zoo, drop = F), by(d, factor(d$Label), f))

or without partial:

s <- do.call(merge.zoo, append(by(d, factor(d$Label), f), list(drop = F)))

For d <- d[d$Label == "A", ] this gives:

           A
2015-03-21 1
2015-03-22 2
2015-03-23 7

Note that the pryr package is required for partial function application.

Upvotes: 0

G. Grothendieck
G. Grothendieck

Reputation: 270348

Use the split= argument of read.zoo to split on the second column:

library(zoo)
read.zoo(d, split = 2)

giving:

           A  B
2015-03-21 1 NA
2015-03-22 2  6
2015-03-23 7  5

Upvotes: 3

Related Questions