Что такое «правое» и «левое» скользящее среднее в R?

Если я хочу рассчитать предыдущие n средние годы с отставанием от текущего года, как мне это сделать? Это так же просто, как «правильное» скользящее среднее окно? Или это «левое» скользящее среднее окно? Я не уверен, какое окно использовать здесь.

Пример данных

set.seed(1234)
dat <- data.frame(year = c(1990:2010), 
                  x = rnorm(21))
dat$x_lag1 <- lag(dat$x, 1)

person Vedda    schedule 01.05.2018    source источник
comment
Это, безусловно, дубликат, пожалуйста, закройте как дубликат   -  person smci    schedule 01.05.2018
comment
Явного обмана не вижу...   -  person Aaron left Stack Overflow    schedule 01.05.2018


Ответы (2)


Может быть, проще думать в терминах смещения. Если вы хотите окно 3, то

  • align = "right" соответствует использованию окна на основе смещений -2, -1, 0, т. е. точки перед предыдущей, предыдущей и текущей точкой. Текущая точка — крайний правый конец окна. Обратите внимание, что rollapplyr с r в конце равносильно указанию align = "right".
  • align = "center" соответствует использованию окна на основе смещений -1, 0, 1, т. е. предыдущей точки, текущей точки и следующей точки. Текущая точка — центр окна. Это значение по умолчанию для align= .
  • align = "left" соответствует использованию окна на основе смещений 0, 1, 2, т.е. текущей точки, следующей точки и точки после этой. Текущей точкой является крайняя левая точка окна.

rollapply позволяет использовать спецификацию align= или нотацию смещения. Чтобы использовать последний для width, укажите список, содержащий один вектор, определяющий смещения. (Фактическая спецификация ширины заключается в указании вектора ширины, по одному для каждого элемента ввода или списка векторов смещения; однако в обоих случаях они повторяются, поэтому обычный случай указания одной скалярной ширины или списка, содержащего одиночный вектор смещения является частным случаем.)

окончание окна в текущей точке

Ниже мы используем align= для получения среднего значения окна из 3, заканчивающегося текущей точкой, а также используем смещения в качестве альтернативы. Мы показываем как фреймы данных, так и объекты зоопарка.

Мы опустили fill=NA для объектов зоопарка, поскольку они в любом случае автоматически выравниваются, поэтому обычно в этом нет необходимости.

library(zoo)

r1 <- transform(dat, roll = rollapplyr(x, 3, mean, fill = NA))

r2 <- transform(dat, roll = rollapply(x, list(seq(-2, 0)), mean, fill = NA))

all.equal(r1, r2)
## [1] TRUE

z <- read.zoo(dat, FUN = identity)
r3 <- rollapplyr(z, 3, mean)

r4 <- rollmeanr(z, 3)

r5 <- rollapply(z, list(seq(-2, 0)), mean) # z from above

all.equal(r3, r4, r5)
## [1] TRUE

окно заканчивается в предыдущей точке

Если вам нужны 3 предыдущие точки, то есть смещения -3, -2, -1, то есть не текущая точка, а 3 точки до нее, тогда будет работать следующее. Обратите внимание, что lag в последней строке требует временного ряда и не должен использоваться с простыми векторами.

# r6 is data frame
r6 <- transform(dat, roll = rollapply(x, list(-seq(3)), mean, fill = NA))

# r7, r8, r9 are zoo objects

r7 <- rollapply(z, list(-seq(3)), mean) # z from above

r8 <- stats::lag(rollapplyr(z, 3, mean), -1)

r9 <- stats::lag(rollmeanr(z, 3), -1)

all.equal(r7, r8, r9)
## [1] TRUE
person G. Grothendieck    schedule 01.05.2018
comment
Отличный ответ! Спасибо. - person Vedda; 01.05.2018

Короче говоря, используйте align = "right". align указывает, будет ли индекс результата left/center/right выровнен по сравнению со скользящим окном наблюдений. Если width=3, align="right", то два наблюдения слева передаются вместе с текущим наблюдением, чтобы FUN вычислить значение по индексу текущего наблюдения.

Можно использовать lag скользящего (align = "right") среднего, чтобы получить mean для предыдущих n наблюдений, исключая текущее наблюдение. Приведенный ниже ответ основан на zoo::rollapply и рассчитывает mean за предыдущие 5 лет.

set.seed(1)
dat <- data.frame(year = c(1990:2010), 
                  x = rnorm(21))

library(dplyr)
library(zoo)
#Mean for previous 5 years can be calculated as:

dat$meanx <- lag(rollapply(dat$x, 5, mean, align = "right", fill=NA))

#Test result
dat[1:10,]
# year          x      meanx
# 1  1990 -0.6264538         NA
# 2  1991  0.1836433         NA
# 3  1992 -0.8356286         NA
# 4  1993  1.5952808         NA
# 5  1994  0.3295078         NA
# 6  1995 -0.8204684 0.12926990
# 7  1996  0.4874291 0.09046698
# 8  1997  0.7383247 0.15122413
# 9  1998  0.5757814 0.46601479
# 10 1999 -0.3053884 0.26211490
# so on
person MKR    schedule 01.05.2018
comment
Отличный ответ. Благодарю вас! - person Vedda; 01.05.2018
comment
Вместо использования lag используйте rollapppy(x, 5, list(-seq(5)), mean, fill = NA) . то есть указать смещения -1, -2, -3, -4, -5. - person G. Grothendieck; 07.03.2019