#r #time-series #average #mean #rollapply
#r #временные ряды #среднее #rollapply
Вопрос:
Может кто-нибудь любезно посоветовать, как лучше всего подойти к созданию нового столбца в dataframe, где каждое наблюдение является средним / средним из предыдущих 12 наблюдений (исключая текущее наблюдение). До сих пор мне не удалось найти аналогичный ответ здесь, так что это было бы с благодарностью!
Мои данные.кадр:
LateCounts <-
Date Count
1 Jan-19 7
2 Feb-19 4
3 Mar-19 9
4 Apr-19 8
5 May-19 7
6 Jun-19 4
7 Jul-19 4
8 Aug-19 5
9 Sep-19 2
10 Oct-19 5
11 Nov-19 7
12 Dec-19 4
13 Jan-20 3
14 Feb-20 4
15 Mar-20 5
16 Apr-20 2
17 May-20 3
18 Jun-20 2
19 Jul-20 3
20 Aug-20 4
21 Sep-20 3
22 Oct-20 2
В настоящее время я использую следующий код:
LateCounts <- LateCounts %>% mutate(RollAvge=rollapplyr(Count, 12, mean, partial = TRUE))
Это дает следующее, кроме скользящего среднего за 12 месяцев:
Date Count RollAvge
1 Jan-19 7 7
2 Feb-19 4 5.5
3 Mar-19 9 6.666667
4 Apr-19 8 7
5 May-19 7 7
6 Jun-19 4 6.5
7 Jul-19 4 6.142857
8 Aug-19 5 6
9 Sep-19 2 5.555556
10 Oct-19 5 5.5
11 Nov-19 7 5.636364
12 Dec-19 4 5.5
13 Jan-20 3 5.166667
14 Feb-20 4 5.166667
15 Mar-20 5 4.833333
16 Apr-20 2 4.333333
17 May-20 3 4
18 Jun-20 2 3.833333
19 Jul-20 3 3.75
20 Aug-20 4 3.666667
21 Sep-20 3 3.75
22 Oct-20 2 3.5
Чего мне действительно нужно достичь, так это следующего. Это конечное или скользящее среднее значение за 12 месяцев (где значения в столбце ‘RollAvge’ являются средними / средними значениями предыдущих значений в столбце ‘Count’, не включая текущий месяц.
Date Count RollAvge
1 Jan-19 7
2 Feb-19 4 7
3 Mar-19 9 5.5
4 Apr-19 8 6.666667
5 May-19 7 7
6 Jun-19 4 7
7 Jul-19 4 6.5
8 Aug-19 5 6.142857
9 Sep-19 2 6
10 Oct-19 5 5.555556
11 Nov-19 7 5.5
12 Dec-19 4 5.636364
13 Jan-20 3 5.5
14 Feb-20 4 5.166667
15 Mar-20 5 5.166667
16 Apr-20 2 4.833333
17 May-20 3 4.333333
18 Jun-20 2 4
19 Jul-20 3 3.833333
20 Aug-20 4 3.75
21 Sep-20 3 3.666667
22 Oct-20 2 3.755556
Спасибо,
Ответ №1:
Нам нужно взять lag
результат, полученный из rollapply
.
library(dplyr)
library(zoo)
LateCounts %>%
mutate(RollAvge= lag(rollapplyr(Count, 12, mean, partial = TRUE)))
-вывод
# Date Count RollAvge
#1 Jan-19 7 NA
#2 Feb-19 4 7.000000
#3 Mar-19 9 5.500000
#4 Apr-19 8 6.666667
#5 May-19 7 7.000000
#6 Jun-19 4 7.000000
#7 Jul-19 4 6.500000
#8 Aug-19 5 6.142857
#9 Sep-19 2 6.000000
#10 Oct-19 5 5.555556
#11 Nov-19 7 5.500000
#12 Dec-19 4 5.636364
#13 Jan-20 3 5.500000
#14 Feb-20 4 5.166667
#15 Mar-20 5 5.166667
#16 Apr-20 2 4.833333
#17 May-20 3 4.333333
#18 Jun-20 2 4.000000
#19 Jul-20 3 3.833333
#20 Aug-20 4 3.750000
#21 Sep-20 3 3.666667
#22 Oct-20 2 3.750000
данные
LateCounts <- structure(list(Date = c("Jan-19", "Feb-19", "Mar-19", "Apr-19",
"May-19", "Jun-19", "Jul-19", "Aug-19", "Sep-19", "Oct-19", "Nov-19",
"Dec-19", "Jan-20", "Feb-20", "Mar-20", "Apr-20", "May-20", "Jun-20",
"Jul-20", "Aug-20", "Sep-20", "Oct-20"), Count = c(7L, 4L, 9L,
8L, 7L, 4L, 4L, 5L, 2L, 5L, 7L, 4L, 3L, 4L, 5L, 2L, 3L, 2L, 3L,
4L, 3L, 2L)), class = "data.frame", row.names = c("1", "2", "3",
"4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22"))
Комментарии:
1. Можно явно указать предыдущие 12 значений, которых следует
rollapply
избегатьlag
, используяLateCounts %>% mutate(RollAvge= rollapplyr(Count, list(-(1:12)), mean, partial = TRUE, fill = NA))
Here-(1:12)
says use смещения -1, -2, …, -12 . Можно указать отдельный вектор смещений для каждой строки или, если указан только один, как здесь, тогда он будет переработан.
Ответ №2:
Используя dplyr и zoo, есть способ сделать это с помощью функции data.frame @NW320d, используя ту же функцию скользящего среднего, но без мутирования и каналов
библиотека (dplyr)
библиотека (зоопарк)
Использование кода LateCounts от @akrun (спасибо за этот фрагмент кода!)
> LateCounts <- structure(list(Date = c("Jan-19", "Feb-19", "Mar-19", "Apr-19",
"May-19", "Jun-19", "Jul-19", "Aug-19", "Sep-19", "Oct-19", "Nov-19",
"Dec-19", "Jan-20", "Feb-20", "Mar-20", "Apr-20", "May-20", "Jun-20",
"Jul-20", "Aug-20", "Sep-20", "Oct-20"), Count = c(7L, 4L, 9L,
8L, 7L, 4L, 4L, 5L, 2L, 5L, 7L, 4L, 3L, 4L, 5L, 2L, 3L, 2L, 3L,
4L, 3L, 2L)), class = "data.frame", row.names = c("1", "2", "3",
"4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22"))
> data.frame(LateCounts$Count, rollavg=dplyr::lag(rollapplyr(LateCounts$Count, 12, mean, partial = TRUE)))
Output:
LateCounts.Count rollavg
1 7 NA
2 4 7.000000
3 9 5.500000
4 8 6.666667
5 7 7.000000
6 4 7.000000
7 4 6.500000
8 5 6.142857
9 2 6.000000
10 5 5.555556
11 7 5.500000
12 4 5.636364
13 3 5.500000
14 4 5.166667
15 5 5.166667
16 2 4.833333
17 3 4.333333
18 2 4.000000
19 3 3.833333
20 4 3.750000
21 3 3.666667
22 2 3.750000