Расчет скользящей средней
Я пытаюсь использовать R для вычисления скользящей средней по ряду значений в матрице. Однако обычный поиск списка рассылки R не был очень полезен. Кажется, нет встроенная функция in R позволит мне рассчитать скользящие средние. Предоставляют ли какие-либо пакеты? Или мне нужно написать свою собственную?
8 ответов
или вы можете просто вычислить его с помощью фильтра, вот функция, которую я использую:
ma <- function(x,n=5){filter(x,rep(1/n,n), sides=2)}
используя cumsum должно быть достаточным и эффективным. Если у вас есть вектор x и вы хотите бегущую сумму n цифры
cx <- c(0,cumsum(x))
rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n
как указано в комментариях @mzuther, это предполагает, что в данных нет NAs. чтобы справиться с ними, потребуется разделить каждое окно на количество значений, отличных от NA. Вот один из способов сделать это, включив комментарий от @Ricardo Cruz:
cx <- c(0, cumsum(ifelse(is.na(x), 0, x)))
cn <- c(0, cumsum(ifelse(is.na(x), 0, 1)))
rx <- cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]
rn <- cn[(n+1):length(cx)] - cx[1:(length(cx) - n)]
rsum <- rx / rn
Это еще вопрос что если все значения в окне NAs, то будет деление на нулевую ошибку.
можно использовать RcppRoll для очень быстрых скользящих средних, написанных на C++. Просто позвоните 
на caTools пакет имеет очень быстрое среднее/мин/макс/СД завальцовки и немногие другие функции. Я работал только с runmean и runsd и они являются самыми быстрыми из любых других пакетов, упомянутых на сегодняшний день.
В самом деле RcppRoll очень хорошо.
код написал cantdutchthis необходимо исправить в четвертой строке, чтобы окно было исправлено:
ma <- function(arr, n=15){
  res = arr
  for(i in n:length(arr)){
    res[i] = mean(arr[(i-n+1):i])
  }
  res
}
другой способ, который обрабатывает пропуски, дается здесь.
третий способ, улучшение cantdutchthis код для расчета частичных средних или нет, следует:
  ma <- function(x, n=2,parcial=TRUE){
  res = x #set the first values
  if (parcial==TRUE){
    for(i in 1:length(x)){
      t<-max(i-n+1,1)
      res[i] = mean(x[t:i])
    }
    res
  }else{
    for(i in 1:length(x)){
      t<-max(i-n+1,1)
      res[i] = mean(x[t:i])
    }
    res[-c(seq(1,n-1,1))] #remove the n-1 first,i.e., res[c(-3,-4,...)]
  }
}
для того чтобы дополнить ответ cantdutchthis и Родриго Практике;
moving_fun <- function(x, w, FUN, ...) {
  # x: a double vector
  # w: the length of the window, i.e., the section of the vector selected to apply FUN
  # FUN: a function that takes a vector and return a summarize value, e.g., mean, sum, etc.
  # Given a double type vector apply a FUN over a moving window from left to the right, 
  #    when a window boundary is not a legal section, i.e. lower_bound and i (upper bound) 
  #    are not contained in the length of the vector, return a NA_real_
  if (w < 1) {
    stop("The length of the window 'w' must be greater than 0")
  }
  output <- x
  for (i in 1:length(x)) {
     # plus 1 because the index is inclusive with the upper_bound 'i'
    lower_bound <- i - w + 1
    if (lower_bound < 1) {
      output[i] <- NA_real_
    } else {
      output[i] <- FUN(x[lower_bound:i, ...])
    }
  }
  output
}
# example
v <- seq(1:10)
# compute a MA(2)
moving_fun(v, 2, mean)
# compute moving sum of two periods
moving_fun(v, 2, sum)
хотя немного медленно, но вы также можете использовать zoo:: rollapply для выполнения вычислений по матрицам.
reqd_ma <- rollapply(x, FUN = mean, width = n)
где x-набор данных, FUN = mean-функция; вы также можете изменить его на min, max, sd и т. д., а ширина-окно качения.
