Скользящее среднее трех предыдущих значений в R

в пакете zoo есть функция rollmean, которая позволяет создавать скользящие средние. The rollmean(x,3) будет принимать предыдущее, текущее и следующее значение (т. е. 4, 6 и 2) в таблице ниже. Это показано во второй колонке.

x   rollmean    ma3
4       
6   4.0 
2   4.3 
5   3.0         4.0
2   6.3         4.3
12  6.0         3.0
4   6.0         6.3
2               6.0

Я хотел бы выполнить ту же работу, но путем усреднения предыдущих 3 значений в четвертой строке. Это отображается в третьем столбце. Может кто-нибудь сказать мне имя функции, которая поможет это осуществить?

3 ответов


Я изо всех сил искал простую функцию для скользящих средних, которая имела некоторую гибкость, чтобы делать то, что мне нужно. Наконец, я написал пару функций, расширяющих ту, которая основана на функции фильтра, которую ринни дает выше в комментарии (но которая сама по себе не будет работать, потому что она будет включать текущее наблюдение в среднем за 3 периода).

  1. функция скользящей средней, которая включает текущее наблюдение

    mav <- function(x,n){filter(x,rep(1/n,n), sides=1)} 
    
  2. переезд средняя функция, которая не включает текущее наблюдение

    mavback <- function(x,n){
      a<-mav(x,1)
      b<-mav(x,(n+1))
      c<-(1/n)*((n+1)*b - a)
      return(c)
    }
    
  3. обратная функция скользящей средней, не включая текущие obs, на основе [h2] показаний, начиная [h1] периоды назад

    mavback1<-function(x,h1,h2){
      a<-mavback(x,h1)
      b<-mavback(x,h1-h2)
      c<-(1/h2)*(h1*a -(h1-h2)*b)
      return(c)
    }
    

можно использовать rollmean, а align='right'. Или вы можете использовать rollmeanr, имеющего align='right' по умолчанию.

ma3 <- rollmeanr(x[,1],3,fill=NA)

...но результат все равно придется отложить. Другое решение-использовать rollapply список для элемента :

ma3 <- rollapplyr(x[,1],list(-(3:1)),mean,fill=NA)

более простая реализация функции mavback w_i_l_l на основе его функции mav

mavback <- function(x,n){ filter(x, c(0, rep(1/n,n)), sides=1) }