Интерполяция нерегулярных временных рядов с помощью R
В поисках линейной интерполяции данных временных рядов в R я часто находил рекомендации по использованию na.approx()
из zoo
пакет.
Однако с нерегулярными временными рядами у меня возникли проблемы, потому что интерполированные значения распределяются равномерно по количеству промежутков, не принимая во внимание связанную временную метку значения.
Я нашел работу с использованием approxfun()
, но мне интересно, есть ли более чистое решение, в идеале основанное на tsibble
объекты с функциями из tidyverts
пакетная семья?
Предыдущие ответы основывались на расширении нерегулярной сетки даты до регулярной сетки путем заполнения пробелов. Однако это вызывает проблемы, когда при интерполяции следует учитывать дневное время.
Вот (исправленный) минимальный пример с меткой времени POSIXct, а не только с датой:
library(tidyverse)
library(zoo)
df <- tibble(date = as.POSIXct(c("2000-01-01 00:00", "2000-01-02 02:00", "2000-01-05 00:00")),
value = c(1,NA,2))
df %>%
mutate(value_int_wrong = na.approx(value),
value_int_correct = approxfun(date, value)(date))
# A tibble: 3 x 4
date value value_int_wrong value_int_correct
<dttm> <dbl> <dbl> <dbl>
1 2000-01-01 00:00:00 1 1 1
2 2000-01-02 02:00:00 NA 1.5 1.27
3 2000-01-05 00:00:00 2 2 2
Есть идеи, как (эффективно) справиться с этим? Спасибо за вашу поддержку!
2 ответа
Вот эквивалентное решение на основе tsibble. Вinterpolate()
функция нуждается в модели, но вы можете использовать случайное блуждание, чтобы дать линейную интерполяцию между точками.
library(tidyverse)
library(tsibble)
library(fable)
#> Loading required package: fabletools
df <- tibble(
date = as.Date(c("2000-01-01", "2000-01-02", "2000-01-05", "2000-01-06")),
value = c(1, NA, 2, 1.5)
) %>%
as_tsibble(index = date) %>%
fill_gaps()
df %>%
model(naive = ARIMA(value ~ -1 + pdq(0,1,0) + PDQ(0,0,0))) %>%
interpolate(df)
#> # A tsibble: 6 x 2 [1D]
#> date value
#> <date> <dbl>
#> 1 2000-01-01 1
#> 2 2000-01-02 1.25
#> 3 2000-01-03 1.5
#> 4 2000-01-04 1.75
#> 5 2000-01-05 2
#> 6 2000-01-06 1.5
Создано 08.04.2020 пакетом correx (v0.3.0)
Лично я бы выбрал решение, которое вы используете, но чтобы показать, как использовать na.approx
в этом случае мы можем complete
последовательность дат перед использованием na.approx
и присоединить его к оригиналу df
чтобы сохранить исходные строки.
library(dplyr)
df %>%
tidyr::complete(date = seq(min(date), max(date), by = "day")) %>%
mutate(value_int = zoo::na.approx(value)) %>%
right_join(df, by = "date") %>%
select(date, value_int)
# date value_int
# <date> <dbl>
#1 2000-01-01 1
#2 2000-01-02 1.25
#3 2000-01-05 2