Скользящее среднее с изменением периода в R

У меня есть фрейм данных с именем abc, на котором я делаю скользящее среднее, используя rollapply. Работает следующий код:

forecast <- rollapply(abc, width=12, FUN=mean, align = "right", fill=NA)

Теперь я хочу сделать то же самое с переменной шириной, т.е. для 1-го месяца она будет пустой, для второго месяца придет значение первого месяца. Для третьего месяца это будет (первый месяц+второй месяц/2), т.е. для i-го месяца, если i<=12, значение будет (sum(1:i-1)/(i-1)), а для i>=12 это будет среднее значение за последние 12 месяцев, как это сделано forecast. Пожалуйста помоги.


person user3815746    schedule 08.07.2014    source источник


Ответы (1)


Вот некоторые подходы:

1) частичное=ИСТИНА

n <- length(x)
c(NA, rollapplyr(x, 12, mean, partial = TRUE)[-n])

Обратите внимание на r в конце rollapplyr.

2) ширина в виде списка Аргумент width функции rollapply может быть списком, в котором i-й элемент списка является вектором смещений, используемых для i-го скользящего вычисления. Если мы укажем partial=TRUE, то смещения, выходящие за конец вектора, будут игнорироваться. Если мы укажем только один элемент в списке, он будет переработан:

rollapply(x, list(-seq(12)), mean, partial = TRUE, fill = NA)

2a) Вместо того, чтобы перерабатывать и в зависимости от partial, мы можем записать его. Здесь нам нужно width <- list(numeric(0), -1, -(1:2), -(1:3), ..., -(1:12), ..., -(1:12)), которое можно рассчитать следующим образом:

width <- lapply(seq_along(x), function(x) -seq_len(min(12, x-1)))
rollapply(x, width, mean)

Это в основном будет представлять интерес, если вы хотите немного изменить спецификацию, потому что она очень гибкая.

Примечание. Позже в комментариях автор попросил использовать то же скользящее среднее, за исключением того, что оно не должно отставать. Это было бы просто:

rollapplyr(x, 12, mean, partial = TRUE)

Обратите внимание на r в конце rollapplyr.

Обновление Некоторые улучшения и дополнительные решения.

person G. Grothendieck    schedule 08.07.2014
comment
@ g-grothendieck Спасибо. Но здесь width принимает все предыдущие значения. сказать: width[10] [1] -1 -2 -3 -4 -5 -6 -7 -8 -9 Это нормально. Но, width[15] [1] -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 это не то, чего я хочу. Я хочу, чтобы вы делали до [12], но после 12 он будет принимать не все предыдущие значения, а только последние 12 значений. то есть ширина постоянна на уровне 12 с 13-го элемента и далее. Итак, width[15] будет: -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 Пожалуйста, смотрите. - person user3815746; 08.07.2014
comment
Изменены, чтобы принимать не более 12 значений. - person G. Grothendieck; 08.07.2014
comment
@ g-grothendieck Еще раз спасибо, это служит моей цели, но я не смог понять мелочь. Какие изменения я должен сделать, если я хочу сдвинуть результаты вверх? Я имею в виду, что хочу, чтобы width[1] было -1 вместо integer(0), width[2] было -1 -2 и так далее. Скажем, в 25-й строке я бы хотел sum(x[14]:x[25])/12 вместо sum(x[13]:x[24])/12. Спасибо. - person user3815746; 08.07.2014
comment
Удалите -1 или просто rollapplyr(x, 12, mean, partial = TRUE). Также обратите внимание на только что добавленное более простое решение. - person G. Grothendieck; 08.07.2014
comment
получение разных результатов. Использование width без -1: [1] 0.08830709 0.08916036 0.09122831 0.09407099 0.09144008 0.09331063 0.09433104 [8] 0.09823444 0.09457298 0.08625747 0.08442378 0.08149499 0.07916721 0.07667792 Использование rollapply(..,partial = TRUE): [1] 0.08055410 0.08334492 0.08765026 0.08788178 0.08664798 0.08830709 0.08916036 0.09122831 0.09407099 0.09144008 0.09331063 0.09433104 0.09823444 0.09457298 0.08625747 0.08442378 0.08149499 [18] 0.07916721 0.07667792 0.07836255 0.07783986 0.08256117 0.08351636 0.08145590 0.06648748 0.06774488 Даже нет. точек данных разные. - person user3815746; 08.07.2014
comment
См. Примечание в конце ответа и не забудьте r в конце rollapplyr. - person G. Grothendieck; 08.07.2014
comment
Хороший ответ @G.Grothendieck, я раньше не знал о функции rollapplyr - person jogall; 08.07.2014
comment
@ Г. Гротендик, спасибо за отличный ответ. Но первый метод в 2a, используя ширину, дает следующий результат [1] NaN 1.000000 1.500000 2.000000 2.500000 3.200000 3.833333 3.714286 [9] 3.750000 3.888889 4.300000, а rollapplyr дает [1] 1.000000 1.500000 2.000000 2.500000 3.200000 3.833333 3.714286 3.750000 [9] 3.888889 4.300000 4.454545 Как мне получить последнее значение, используя функцию ширины? - person user3815746; 10.07.2014
comment
Примечание относится к проблеме, отличной от предыдущего кода, поэтому ясно, что ответ будет другим. - person G. Grothendieck; 10.07.2014