Интерполяция нерегулярных временных рядов с R - PullRequest
2 голосов
/ 07 апреля 2020

При поиске линейной интерполяции данных временного ряда в 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 ]

1 голос
/ 08 апреля 2020

Вот эквивалентное решение на основе Циббл. Для функции 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

Создано в 2020-04-08 пакетом Представить (v0.3.0)

0 голосов
/ 07 апреля 2020

Лично я бы go использовал решение, которое вы используете, но чтобы показать, как использовать 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   
...