我有一个看起来像这样的数据帧:
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)
但这看起来与我做霍尔特温特斯模型所需要的并不接近。我已经查看了堆栈溢出以及 TS 和 Zoo 的文档,我坚持如何创建这个 TS 对象。朝着正确的方向推动将不胜感激。
TS 对象通常用于月度、季度或年度数据,而不是每日数据;但是,如果我们删除 2 月 29 日,那么我们可以创建一个 ts 对象,其时间是年份加上分数 0/365、1/365、...、364/365,如果没有丢失日期,它将定期间隔。 关键的一点是,如果季节性是基于一年的,那么我们必须在每年有相同数量的点来表示它作为 ts 对象。
首先转换为具有普通日期的动物园对象 z0,删除 2 月 29 日给出 z,在动物园对象 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"
))