我有一个时间序列,我想智能地插入缺失值。特定时间的值受到多天趋势的影响,以及它在每日周期中的位置。
以下是myzoo
中缺少第十个观察值的示例
start <- as.POSIXct("2010-01-01")
freq <- as.difftime(6, units = "hours")
dayvals <- (1:4)*10
timevals <- c(3, 1, 2, 4)
index <- seq(from = start, by = freq, length.out = 16)
obs <- (rep(dayvals, each = 4) + rep(timevals, times = 4))
myzoo <- zoo(obs, index)
myzoo[10] <- NA
如果我必须实现这一点,我会使用附近几天的某种加权平均收盘时间,或者将当天的值添加到适合更大趋势的函数线,但我希望已经存在一些适用于这种情况的包或函数?
编辑:稍微修改了代码,以澄清我的问题。有一些na.*
方法可以从最近的邻居处进行插值,但在这种情况下,它们不会识别缺失值位于当天的最低值的时间。也许解决方案是将数据重塑为宽格式,然后进行插值,但我不想完全忽略同一天的邻接值。值得注意的是,diff(myzoo, lag = 4)
返回一个10的向量。解决方案可能在于reshape
、na.spline
和diff.inv
的某种组合,但我就是想不出来。
以下是三种不起作用的方法:
EDIT2。使用以下代码生成的图像。
myzoo <- zoo(obs, index)
myzoo[10] <- NA # knock out the missing point
plot(myzoo, type="o", pch=16) # plot solid line
points(na.approx(myzoo)[10], col = "red")
points(na.locf(myzoo)[10], col = "blue")
points(na.spline(myzoo)[10], col = "green")
myzoo[10] <- 31 # replace the missing point
lines(myzoo, type = "o", lty=3, pch=16) # dashed line over the gap
legend(x = "topleft",
legend = c("na.spline", "na.locf", "na.approx"),
col=c("green","blue","red"), pch = 1)
发布于 2011-02-11 11:45:23
试试这个:
x <- ts(myzoo,f=4)
fit <- ts(rowSums(tsSmooth(StructTS(x))[,-2]))
tsp(fit) <- tsp(x)
plot(x)
lines(fit,col=2)
其思想是使用时间序列的基本结构模型,该模型使用卡尔曼滤波器精细地处理缺失值。然后使用卡尔曼平滑法估计时间序列中的每个点,包括任何省略的点。
为了使用StructTS,我不得不将你的zoo对象转换为频率为4的ts对象。您可能希望再次将拟合值更改回zoo。
发布于 2011-02-11 02:52:27
在这种情况下,我认为您需要在ARIMA模型中进行季节性校正。这里没有足够的日期来适应季节模型,但这应该可以让你开始。
library(zoo)
start <- as.POSIXct("2010-01-01")
freq <- as.difftime(6, units = "hours")
dayvals <- (1:4)*10
timevals <- c(3, 1, 2, 4)
index <- seq(from = start, by = freq, length.out = 16)
obs <- (rep(dayvals, each = 4) + rep(timevals, times = 4))
myzoo <- myzoo.orig <- zoo(obs, index)
myzoo[10] <- NA
myzoo.fixed <- na.locf(myzoo)
myarima.resid <- arima(myzoo.fixed, order = c(3, 0, 3), seasonal = list(order = c(0, 0, 0), period = 4))$residuals
myzoo.reallyfixed <- myzoo.fixed
myzoo.reallyfixed[10] <- myzoo.fixed[10] + myarima.resid[10]
plot(myzoo.reallyfixed)
points(myzoo.orig)
在我的测试中,ARMA(3,3)非常接近,但这只是运气。对于较长的时间序列,您应该能够校准季节性校正,以提供良好的预测。对信号和季节校正的潜在机制有一个很好的先验,以获得更好的样本性能,这将是有帮助的。
发布于 2016-03-22 00:57:23
forecast::na.interp
是一个很好的方法。从documentation
对非季节性序列使用线性插值,并使用季节性序列的周期性stl分解来替换缺失值。
library(forecast)
fit <- na.interp(myzoo)
fit[10] # 32.5, vs. 31.0 actual and 32.0 from Rob Hyndman's answer
This paper针对实时序列评估了几种插值方法,并发现na.interp
既准确又高效:
本文测试的R实现中的
、预测包中的na.interp和zoo包中的na.StructTS显示了最佳的总体结果。
na.interp函数也不会比最快的方法na.approx慢太多,因此在计算时间方面,loess分解似乎不是很苛刻。
同样值得注意的是,Rob Hyndman编写了forecast
包,并在提供了对此问题的答案后包含了na.interp
。na.interp
很可能是对这种方法的改进,尽管它在这种情况下表现较差(可能是因为在StructTS
中指定了句点,na.interp
会找出答案)。
https://stackoverflow.com/questions/4964255
复制相似问题