R在zoo对象和数据框之间转换,结果对于不同数量的列不一致?

Sil*_*ish 10 r dataframe zoo

我在数据框和动物园对象之间切换很困难,特别是保留有意义的列名,以及单变量和多变量情况之间的不一致:

library(zoo)

#sample data, two species counts over time
t = as.Date(c("2012-01-01", "2012-01-02", "2012-01-03", "2012-01-04"))
n1 = c(4, 5, 9, 7)  #counts of Lepisma saccharina
n2 = c(2, 6, 0, 11) #counts of Thermobia domestica
df = data.frame(t, n1, n2)
colnames(df) <- c("Date", "Lepisma saccharina", "Thermobia domestica")

#converting to zoo loses column names in univariate case...
> z1 <- read.zoo(df[,1:2]) #time series for L. saccharina
> colnames(z1)
NULL
> colnames(z1) <- c("Lepisma saccharina") #can't even set column name manually
Error in `colnames<-`(`*tmp*`, value = "Lepisma saccharina") : 
  attempt to set colnames on object with less than two dimensions
#... but not in multivariate case
> z2 <- read.zoo(df) #time series for both species
> colnames(z2)
[1] "Lepisma saccharina"  "Thermobia domestica"
Run Code Online (Sandbox Code Playgroud)

要从动物园对象返回到原始格式的数据框,使用它是不够的,as.data.frame因为它不包含Date列(日期最终在rownames中):需要做更多的工作.

zooToDf <- function(z) {
    df <- as.data.frame(z) 
    df$Date <- time(z) #create a Date column
    rownames(df) <- NULL #so row names not filled with dates
    df <- df[,c(ncol(df), 1:(ncol(df)-1))] #reorder columns so Date first
    return(df)
}
Run Code Online (Sandbox Code Playgroud)

这在多变量情况下效果很好,但显然无法在单变量情况下恢复有意义的列名:

> df2b <- zooToDf(z2)
> df2b
        Date Lepisma saccharina Thermobia domestica
1 2012-01-01                  4                   2
2 2012-01-02                  5                   6
3 2012-01-03                  9                   0
4 2012-01-04                  7                  11

> df1b <- zooToDf(z1)
> df1b
        Date z
1 2012-01-01 4
2 2012-01-02 5
3 2012-01-03 9
4 2012-01-04 7
Run Code Online (Sandbox Code Playgroud)

有一个简单的方法来处理这两个单变量多变量的情况?似乎z1需要以某种方式记住列名.

Jos*_*ich 15

如果您不想删除尺寸,请使用drop=FALSE:

R> (z1 <- read.zoo(df[,1:2], drop=FALSE))
           Lepisma saccharina
2012-01-01                  4
2012-01-02                  5
2012-01-03                  9
2012-01-04                  7
Run Code Online (Sandbox Code Playgroud)

你可以这样做write.zoo,如果你想包括动物园指数在data.frame列:

zoo.to.data.frame <- function(x, index.name="Date") {
  stopifnot(is.zoo(x))
  xn <- if(is.null(dim(x))) deparse(substitute(x)) else colnames(x)
  setNames(data.frame(index(x), x, row.names=NULL), c(index.name,xn))
}
Run Code Online (Sandbox Code Playgroud)

更新:

在尝试编辑您的问题以简洁之后,我想到了一种简单的方法来创建df2b您的规范(z1如果您不删除维度,这也适用):

R> (df2b <- data.frame(Date=time(z2), z2, check.names=FALSE, row.names=NULL))
        Date Lepisma saccharina Thermobia domestica
1 2012-01-01                  4                   2
2 2012-01-02                  5                   6
3 2012-01-03                  9                   0
4 2012-01-04                  7                  11
Run Code Online (Sandbox Code Playgroud)

  • fortify.zoo(z1)? (3认同)

G. *_*eck 5

要将数据框转换为动物园,请使用read.zoo

library(zoo)
z <- read.zoo(df)
Run Code Online (Sandbox Code Playgroud)

drop另请注意中 和其他参数的可用性?read.zoo

要将动物园转换为数据框(包括索引),请使用fortify.zoo

fortify.zoo(z, name = "Date")
Run Code Online (Sandbox Code Playgroud)

(如果 ggplot2 已加载,那么您可以只使用fortify。)

正如问题下面的评论中提到的,该问题以及其他一些答案要么已经过时,要么存在一些重大误解。建议您查看https://cran.r-project.org/web/packages/zoo/vignettes/zoo-design.pdf,其中讨论了zoo的设计理念,其中包括与R本身的一致性。当然,如果您必须记住一组 R 的默认值和另一组 Zoo 的默认值,那么 Zoo 的使用会困难得多。