Создание временного ряда ts с пропущенными значениями из фрейма данных - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть фрейм данных, содержащий временной ряд ежемесячных данных с некоторыми пропущенными значениями.

dates <- seq(
  as.Date("2010-01-01"), as.Date("2017-12-01"), "1 month"
)
n_dates <- length(dates)
dates <- dates[runif(n_dates) < 0.5]
time_data <- data.frame(
  date = dates,
  value = rnorm(length(dates))
)
##          date      value
## 1  2010-02-01  1.3625419
## 2  2010-06-01  0.1512481
## etc.

Для того, чтобы можно было использовать функцию прогнозирования временных рядов, например, forecastЯ хотел бы преобразовать это в ts объект.

Глупый способ сделать это состоит в том, чтобы создать регулярный набор ежемесячных дат в течение всего периода времени, а затем снова присоединиться к исходным данным..

library(dplyr)
first_date <- min(time_data$date)
last_date <- max(time_data$date)
full_dates <- data.frame(
  date = seq(first_date, last_date, "1 month")
)
extended_time_data <- left_join(full_dates, time_data, by = "date")
##          date      value
## 1  2010-02-01  1.3625419
## 2  2010-03-01         NA
## etc.

Теперь я могу создавать временные ряды, используя ts().

library(lubridate)
time_series <- ts(
  extended_time_data$value, 
  start = c(year(first_date), month(first_date)),
  frequency = 12
)

Для такой простой задачи это многословно и довольно грубо.

Я также посмотрел на первое преобразование в xts и использование конвертора из пакета timetk, но ничто не выскочило на меня как более легкий путь.

Этот вопрос является обманом Как создать временной ряд с пропущенными значениями даты и времени , но ответ там был еще более размытым.

Как создать объект ts из временного ряда с пропущенными значениями?

Ответы [ 3 ]

0 голосов
/ 24 сентября 2018

Используя входной фрейм данных, определенный в примечании в конце, преобразуйте его в объект зоопарка с индексом класса yearmon.Затем as.ts преобразует его в ts.

library(zoo)

z <- read.zoo(DF, FUN = as.yearmon)
as.ts(z)
##      Jan Feb Mar Apr May Jun Jul Aug
## 2000   1  NA  NA   2   3  NA   4   5

Если вы предпочитаете выразить его в терминах каналов:

library(magrittr)
library(zoo)

DF %>% read.zoo(FUN = as.yearmon) %>% as.ts

При желании интерполируйте значения во времениряды с использованием na.locf (последнее вхождение перенесено вперед), * ​​1011 * (линейная интерполяция), na.spline, na.StructTS (сезонный фильтр Калмана) или другая функция заполнения зоопарка.например,

library(forecast)

DF %>% read.zoo(FUN = as.yearmon) %>% as.ts %>% na.spline %>% forecast

Примечание

Данные в вопросе не могут быть воспроизведены, поскольку случайные числа используются без set.seed, а n_dates не определено.Ниже мы определяем кадр данных DF воспроизводимо для целей примера.

library(zoo)

dates <- as.Date(as.yearmon("2000-01") + c(0, 3, 4, 6, 7)/12)
DF <- data.frame(dates, values = seq_along(dates))

, давая:

> DF
       dates values
1 2000-01-01      1
2 2000-04-01      2
3 2000-05-01      3
4 2000-07-01      4
5 2000-08-01      5
0 голосов
/ 24 сентября 2018
Опция

A base и использование set.seed(789) перед запуском генерации данных

temp <- which(full_dates$date%in%time_data$date)
full_dates$new[temp] <- time_data$value
head(full_dates, 20)

         date         new
1  2010-02-01  0.62589399
2  2010-03-01  0.98117664
3  2010-04-01          NA
4  2010-05-01 -0.04770986
5  2010-06-01 -1.51961483
6  2010-07-01          NA
7  2010-08-01  0.79493644
8  2010-09-01 -0.14423251
9  2010-10-01 -0.70649791
10 2010-11-01  0.61071247
11 2010-12-01          NA
12 2011-01-01  1.08506164
13 2011-02-01 -0.71134925
14 2011-03-01  1.15628805
15 2011-04-01  1.23556280
16 2011-05-01 -0.32245531
17 2011-06-01          NA
18 2011-07-01          NA
19 2011-08-01  0.73277540
20 2011-09-01 -0.28752883

или тот же результат, но с использованием data.table

setDT(full_dates)[temp, new:= time_data$value]

Теперь до xts

xts::xts(full_dates[,-1], order.by = full_dates$date,  frequency = 12 )
0 голосов
/ 24 сентября 2018

Вместо использования left_join более простой вариант - complete, преобразуйте его в tsibble объект, который теперь совместим с forecast функциями пакета

library(tidyverse)
library(tsibble)
time_data %>% 
  complete(date = seq(min(date), max(date), by = "1 month"), 
        fill = list(value = NA)) %>%
  as_tsibble(index = date)


# A tsibble: 94 x 2 [1D]
#   date         value
#   <date>       <dbl>
# 1 2010-02-01   1.02 
# 2 2010-03-01  NA    
# 3 2010-04-01  NA    
# 4 2010-05-01   1.75 
# 5 2010-06-01  NA    
# 6 2010-07-01  NA    
# 7 2010-08-01  -0.233
# 8 2010-09-01  NA    
# 9 2010-10-01  NA    
#10 2010-11-01  -0.987
# ... with 84 more rows

Как уже упоминалось выше,он совместим с forecast функциями

library(fable)
time_data %>% 
   complete(date = seq(min(date), max(date), by = "1 month"), 
         fill = list(value = 0)) %>% 
   as_tsibble(index = date) %>%
   ETS(value) %>% 
   forecast %>%
   autoplot

ПРИМЕЧАНИЕ: здесь пропущенные значения вменяются как 0.

enter image description here

Это может быть вменено с предыдущим значением не-NA с fill

time_data %>% 
   complete(date = seq(min(date), max(date), by = "1 month")) %>% 
   fill(value) %>% 
   as_tsibble(index = date) %>% 
   ETS(value) %>%
   forecast %>%
   autoplot

data

n_dates <- 3
...