Как мы можем обнаружить и удалить переменные с промежуточными НП и рассчитать АКФ для нескольких временных рядов?
Вот данные моего игрушечного временного ряда:
library(tidyverse); library(tsibble); library(feasts)
df <- tibble::tribble(
~date, ~A, ~B, ~C,
"1/31/2010", NA, 0.017, NA,
"2/28/2010", NA, 0.027, NA,
"3/31/2010", NA, 0.003, 0.003,
"4/30/2010", -0.022, 0.018, 0.018,
"5/31/2010", -0.036, 0.02, 0.02,
"6/30/2010", -0.046, 0.023, 0.023,
"7/31/2010", NA, 0.027, 0.027,
"8/31/2010", -0.022, 0.008, 0.008,
"9/30/2010", 0.059, -0.003, -0.003,
"10/31/2010", 0.024, 0.058, 0.058,
"11/30/2010", NA, 0.023, NA,
"12/31/2010", NA, 0.014, NA
)
Я хочу рассчитать автокорреляцию (acf) нескольких временных рядов. Игнорируя часть вменения, мне нужно:
- Удалите переменные с промежуточными NA (не в начале и конце временного ряда), например NA 31.07.2010 для A. Итак, в этом случае удалите переменную A.
- Рассчитайте автокорреляцию, потенциально используя функцию ACF из пакета праздников на B и C.
Я тут начал и застрял:
df %>%
mutate(date = mdy(date)) %>%
pivot_longer(cols = -date) %>%
as_tsibble(key = name, index = date) %>%
ACF()
Ожидаемый результат будет иметь автокорреляцию всех возможных серий с задержкой. Как B будет иметь 10-11 значений для 10 лагов и то же самое для серии B
1 ответ
Решение
Что касается части 1
Мы можем использовать rle
. Определим краткую настраиваемую функциюhas_middle_NA
has_middle_NA <- function(x) {
rl <- rle(is.na(x))$values
any(rl[-c(1, length(rl))])
}
потом
df %>%
group_by(date) %>%
select_if(~ !has_middle_NA(.x)) %>%
ungroup()
## A tibble: 12 x 3
# date B C
# <chr> <dbl> <dbl>
# 1 1/31/2010 0.017 NA
# 2 2/28/2010 0.027 NA
# 3 3/31/2010 0.003 0.003
# 4 4/30/2010 0.018 0.018
# 5 5/31/2010 0.02 0.02
# 6 6/30/2010 0.023 0.023
# 7 7/31/2010 0.027 0.027
# 8 8/31/2010 0.008 0.008
# 9 9/30/2010 -0.003 -0.003
#10 10/31/2010 0.058 0.058
#11 11/30/2010 0.023 NA
#12 12/31/2010 0.014 NA
Это удаляет все столбцы с NA
s, не ведущие и не замыкающие.
Что касается части 2
Мне все еще не совсем понятно, что вы пытаетесь сделать с ACF на основе предоставленных вами данных; но, возможно, это помогает.
Главное - рассматривать ваши данные как данные за месяц, игнорируя день. Тогда мы можем:
- Преобразуйте свои данные в ежемесячные данные, используя
zoo::yearmon
, - Выберите те столбцы, в которых нет
NA
s "посередине", - Преобразование от широкого к длинному и создание
tsibble
из каждого столбца, - Использовать
feasts::ACF
чтобы вычислить ACF для каждого столбца и сохранить результат вlist
столбецtsibble
s
library(tsibble)
library(tidyverse)
library(feasts)
library(zoo)
df <- df %>%
mutate(date = as.yearmon(date, format = "%m/%d/%Y")) %>%
group_by(date) %>%
select_if(~ !has_middle_NA(.x)) %>%
ungroup() %>%
pivot_longer(-date) %>%
group_by(name) %>%
nest() %>%
mutate(
data = map(data, as_tsibble),
ACF = map(data, ACF))
## A tibble: 2 x 3
## Groups: name [2]
# name data ACF
# <chr> <list> <list>
#1 B <tsibble [12 × 2]> <tsibble [10 × 2]>
#2 C <tsibble [12 × 2]> <tsibble [7 × 2]>