在 R 中,如何通过 by 和 zoo 维护列名?

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

我有一个长格式 data.frame,我想用它来构建一个宽格式 zoo 系列。

data.frame 看起来像:

        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
...

例如:

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

我的结果应该是 zoo,看起来像:

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

我已经成功地使用了:

f <- function(x) {

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

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

其中 ddata.frame

但是,当 d 只包含一个 Label 时,它会将列名称丢弃在某处:

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

names(d) 给出 NULL

如何维护列名,即使输出 zoo 是单变量?

问题是 merge.zoo 默认情况下会删除单变量 zoo 的名称。

可以通过将 drop = F 传递给 args 列表来覆盖此行为。当使用 do.call 时,我们可以使用 merge.zoo 的部分函数应用来实现这一点:

f <- function(x) {

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

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

或没有部分:

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

对于 d <- d[d$Label == "A", ] 这给出:

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

注意部分函数应用需要pryr包。

使用 read.zoosplit= 参数在第二列拆分:

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

给予:

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