我在数据框和动物园对象之间切换很困难,特别是保留有意义的列名,以及单变量和多变量情况之间的不一致:
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"
要从动物园对象返回到原始格式的数据框,使用as.data.frame
是不够的,因为它不包含日期列(日期最终在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)
}
这在多变量情况下效果很好,但显然无法在单变量情况下恢复有意义的列名:
> 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
是否有一种简单的方法来处理 单变量和多变量案例?似乎z1
需要以某种方式记住列名。
答案 0 :(得分:16)
如果您不想删除尺寸,请使用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
如果要将zoo索引作为data.frame中的列包含,可以执行write.zoo
之类的操作:
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))
}
更新:
为了简洁起见,我尝试编辑您的问题后,我想到了一种简单的方法来创建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
答案 1 :(得分:2)
要从数据帧转换为动物园,请使用read.zoo
:
library(zoo)
z <- read.zoo(df)
还要注意drop
和?read.zoo
中其他参数的可用性。
并使用fortify.zoo
:将动物园从数据帧转换为数据帧,包括索引:
fortify.zoo(z, name = "Date")
(如果已加载ggplot2,则可以只使用fortify
。)
正如该问题下面的评论中所述,该问题以及其他一些答案要么已过时,要么存在重大误解。建议您阅读https://cran.r-project.org/web/packages/zoo/vignettes/zoo-design.pdf,其中讨论了Zoo的设计理念,其中包括与R本身的一致性。如果您必须记住R的一组默认值和Zoo的另一组默认值,肯定会更难使用Zoo。
答案 2 :(得分:1)
使用timetk
软件包对此有一个更新的简单解决方案。它将包括xts
和zoo
在内的几种时间序列格式转换为tibble
s。只需包装as.data.frame
即可获得数据框。
timetk::tk_tbl(zoo::read.zoo(df))
# A tibble: 4 x 3
index `Lepisma saccharina` `Thermobia domestica`
<date> <dbl> <dbl>
1 2012-01-01 4 2
2 2012-01-02 5 6
3 2012-01-03 9 0
4 2012-01-04 7 11
答案 3 :(得分:0)
我想绕点一点。首先,将动物园写入csv文件,然后再将其读取到data.frame。索引列默认名为“索引”,但您可以使用参数更改它。
library(zoo)
date <-
seq.Date(
from = as.Date("2017-01-01"),
to = as.Date("2017-01-10"),
by = "days"
)
value <- seq.int(from = 100, to = length(date))
vzoo <- zoo(value, date)
write.zoo(
vzoo,
index.name = "Date",
file = "tmp.txt",
sep = ",",
col.names = TRUE
)
vzoo.df <- read.csv("tmp.txt", sep = ',')
答案 4 :(得分:0)
您可以简单地创建一个新数据集并添加as.data.frame来包装fortify.zoo。这应该有所帮助。 z2 = as.data.frame(fortify.zoo(z,name =“ Date”))