时间序列中的线性插值缺失值
linear interpolate missing values in time series
我想在 data.frame
中添加最小日期和最大日期之间的所有缺失日期,并对所有缺失值进行线性插值,例如
df <- data.frame(date = as.Date(c("2015-10-05","2015-10-08","2015-10-09",
"2015-10-12","2015-10-14")),
value = c(8,3,9,NA,5))
date value
2015-10-05 8
2015-10-08 3
2015-10-09 9
2015-10-12 NA
2015-10-14 5
date value approx
2015-10-05 8 8
2015-10-06 NA 6.33
2015-10-07 NA 4.67
2015-10-08 3 3
2015-10-09 9 9
2015-10-10 NA 8.20
2015-10-11 NA 7.40
2015-10-12 NA 6.60
2015-10-13 NA 5.80
2015-10-14 5 5
dplyr
和 approx
是否有明确的解决方案?
(我不喜欢我的 10 行 for
循环代码。)
这是一种方法。我使用第一个和最后一个日期创建了一个包含一系列日期的数据框。使用 dplyr
包中的 full_join()
,我合并了数据框和 mydf
。然后我在 zoo 包中使用 na.approx()
来处理 mutate()
部分中的插值。
mydf <- data.frame(date = as.Date(c("2015-10-05","2015-10-08","2015-10-09",
"2015-10-12","2015-10-14")),
value = c(8,3,9,NA,5))
library(dplyr)
library(zoo)
data.frame(date = seq(mydf$date[1], mydf$date[nrow(mydf)], by = 1)) %>%
full_join(mydf, by = "date") %>%
mutate(approx = na.approx(value))
# date value approx
#1 2015-10-05 8 8.000000
#2 2015-10-06 NA 6.333333
#3 2015-10-07 NA 4.666667
#4 2015-10-08 3 3.000000
#5 2015-10-09 9 9.000000
#6 2015-10-10 NA 8.200000
#7 2015-10-11 NA 7.400000
#8 2015-10-12 NA 6.600000
#9 2015-10-13 NA 5.800000
#10 2015-10-14 5 5.000000
这里有一些解决方案。
1) zoo 将数据框转换为动物园系列并使用 na.approx
和 xout=
连续日期以获得最终系列
library(zoo)
z <- read.zoo(mydf)
zz <- na.approx(z, xout = seq(start(z), end(z), "day"))
给予:
> zz
2015-10-05 2015-10-06 2015-10-07 2015-10-08 2015-10-09 2015-10-10 2015-10-11
8.000000 6.333333 4.666667 3.000000 9.000000 8.200000 7.400000
2015-10-12 2015-10-13 2015-10-14
6.600000 5.800000 5.000000
将它保留为动物园形式可能更方便,这样您就可以使用动物园的所有设施,但如果您需要数据框形式,只需使用
DF <- fortify.zoo(zz)
1a) zoo/magrittr 以上也可以表示为 magrittr 管道:
library(magrittr)
df %>% read.zoo %>% na.approx(xout = seq(start(.), end(.), "day")) %>% fortify.zoo
(如果需要动物园输出,则省略 fortify.zoo
部分)。
2) base R 我们基本上可以在没有像这样的包的情况下做同样的事情:
n <- nrow(mydf)
with(mydf, data.frame(approx(date, value, xout = seq(date[1], date[n], "day"))))
如果您使用 Forecast 包,我认为您的代码看起来会更加清晰和简单。
library(forecast)
x <- zoo(df$value,df$date)
x <- as.ts(x)
x <- na.interp(x)
print(x)
另一个不错的简短解决方案(使用 imputeTS):
library(imputeTS)
x <- zoo(df$value,df$date)
x <- na.interpolation(x, option = "linear")
print(x)
我想在 data.frame
中添加最小日期和最大日期之间的所有缺失日期,并对所有缺失值进行线性插值,例如
df <- data.frame(date = as.Date(c("2015-10-05","2015-10-08","2015-10-09",
"2015-10-12","2015-10-14")),
value = c(8,3,9,NA,5))
date value
2015-10-05 8
2015-10-08 3
2015-10-09 9
2015-10-12 NA
2015-10-14 5
date value approx
2015-10-05 8 8
2015-10-06 NA 6.33
2015-10-07 NA 4.67
2015-10-08 3 3
2015-10-09 9 9
2015-10-10 NA 8.20
2015-10-11 NA 7.40
2015-10-12 NA 6.60
2015-10-13 NA 5.80
2015-10-14 5 5
dplyr
和 approx
是否有明确的解决方案?
(我不喜欢我的 10 行 for
循环代码。)
这是一种方法。我使用第一个和最后一个日期创建了一个包含一系列日期的数据框。使用 dplyr
包中的 full_join()
,我合并了数据框和 mydf
。然后我在 zoo 包中使用 na.approx()
来处理 mutate()
部分中的插值。
mydf <- data.frame(date = as.Date(c("2015-10-05","2015-10-08","2015-10-09",
"2015-10-12","2015-10-14")),
value = c(8,3,9,NA,5))
library(dplyr)
library(zoo)
data.frame(date = seq(mydf$date[1], mydf$date[nrow(mydf)], by = 1)) %>%
full_join(mydf, by = "date") %>%
mutate(approx = na.approx(value))
# date value approx
#1 2015-10-05 8 8.000000
#2 2015-10-06 NA 6.333333
#3 2015-10-07 NA 4.666667
#4 2015-10-08 3 3.000000
#5 2015-10-09 9 9.000000
#6 2015-10-10 NA 8.200000
#7 2015-10-11 NA 7.400000
#8 2015-10-12 NA 6.600000
#9 2015-10-13 NA 5.800000
#10 2015-10-14 5 5.000000
这里有一些解决方案。
1) zoo 将数据框转换为动物园系列并使用 na.approx
和 xout=
连续日期以获得最终系列
library(zoo)
z <- read.zoo(mydf)
zz <- na.approx(z, xout = seq(start(z), end(z), "day"))
给予:
> zz
2015-10-05 2015-10-06 2015-10-07 2015-10-08 2015-10-09 2015-10-10 2015-10-11
8.000000 6.333333 4.666667 3.000000 9.000000 8.200000 7.400000
2015-10-12 2015-10-13 2015-10-14
6.600000 5.800000 5.000000
将它保留为动物园形式可能更方便,这样您就可以使用动物园的所有设施,但如果您需要数据框形式,只需使用
DF <- fortify.zoo(zz)
1a) zoo/magrittr 以上也可以表示为 magrittr 管道:
library(magrittr)
df %>% read.zoo %>% na.approx(xout = seq(start(.), end(.), "day")) %>% fortify.zoo
(如果需要动物园输出,则省略 fortify.zoo
部分)。
2) base R 我们基本上可以在没有像这样的包的情况下做同样的事情:
n <- nrow(mydf)
with(mydf, data.frame(approx(date, value, xout = seq(date[1], date[n], "day"))))
如果您使用 Forecast 包,我认为您的代码看起来会更加清晰和简单。
library(forecast)
x <- zoo(df$value,df$date)
x <- as.ts(x)
x <- na.interp(x)
print(x)
另一个不错的简短解决方案(使用 imputeTS):
library(imputeTS)
x <- zoo(df$value,df$date)
x <- na.interpolation(x, option = "linear")
print(x)