将数据框转换为 R 中的 TS 对象

Converting a data frame into TS object in R

我有一个如下所示的数据框:

  DAY     X1996 X1997 
1 1-Jul    98    86   
2 2-Jul    97    90   
3 3-Jul    97    93   
....

我想以一个 TS 对象结束,这样我就可以对其进行 HoltWinters 平滑处理。 我想我希望它看起来像这样(虽然我不确定,因为我以前没有做过 HoltWinters):

Day    Year   Temp
1-Jul  1996   98
2-Jul  1996   98
3-Jul  1996   98
...
1-Jul  1997   86
2-Jul  1997   90
3-Jul  1997   93

这就是我想要做的:

df <- read.delim("temps.txt")
myts <- as.ts(df)

但这看起来并不接近我需要做的 Holtwinters 模型。我查看了整个 Whosebug 以及 TS 和 Zoo 的文档,但我一直在研究如何创建这个 TS 对象。向正确的方向推动将不胜感激。

ts对象通常用于月度、季度或年度数据,而不是每日数据;但是,如果我们删除 Feb 29th,那么我们可以创建一个 ts 对象,其时间是年份加上一个小数 0/365、1/365、...、364/365,如果没有缺失日期,它将定期间隔。关键是,如果季节性是基于一年那么我们必须在每一年都有相同数量的点来表示它作为一个ts对象。

首先转换为具有普通日期的动物园对象 z0,删除给出 z 的 Feb 29th,在动物园对象 zz 中创建上述时间索引,然后将其转换为 ts。

library(data.table)
library(lubridate)
library(zoo)

m <- melt(as.data.table(df), id.vars = 1)
z0 <- with(m, zoo(value, as.Date(paste(variable, DAY), "X%Y %d-%b")))
z <- z0[! (month(time(z)) == 2 & day(time(z)) == 29)]  

tt <- time(z)
zz <- zoo(coredata(z), year(tt) + (yday(tt) - ((month(tt) > 2) & leap_year(tt)) - 1)/365)
as.ts(zz)

去掉闰年的 12 月 31 日

上面我们删除了闰年的 2 月 29 日,但另一种方法是删除闰年的 12 月 31 日,给出稍微简单的代码,避免需要使用 leap_year,因为我们可以简单地删除任何一天yday 是 366。z0 从上面看。

zz0 <- z0[yday(time(z0)) <= 365]
tt <- time(zz0)
zz <- zoo(coredata(zz0), year(tt) + (yday(tt) - 1) / 365)
as.ts(zz)

每月汇总

另一种方法是将数据减少为每月数据。然后它相对简单,因为 ts 具有表示月度数据的设施。下面我们使用每个月的最后一个点,但如果需要,我们可以使用平均值或其他标量摘要。

ag <- aggregate(z0, as.yearmon, tail, 1)  # use last point in each month
as.ts(ag)

备注

题中的df做成可重现的形式如下(但是,我们需要用更多的数据来填充它,以避免生成一个有很多NA的ts对象)。

df <- structure(list(DAY = structure(1:3, .Label = c("1-Jul", "2-Jul", 
"3-Jul"), class = "factor"), X1996 = c(98L, 97L, 97L), X1997 = c(86L, 
90L, 93L)), class = "data.frame", row.names = c("1", "2", "3"
))