Obliczanie średniej ruchomej

Próbuję użyć R do obliczenia średniej ruchomej dla szeregu wartości w macierzy. Normalne wyszukiwanie na liście dyskusyjnej R nie było jednak zbyt pomocne. Nie wydaje się, aby Wbudowana Funkcja W R pozwoliła mi obliczyć średnie kroczące. Czy są jakieś Pakiety? Czy muszę pisać własne?

Author: Gregor, 2009-04-13

8 answers

  • Rolling Means/Maximums / Medians in the zoo package (rollmean)
  • MovingAverages in TTR
  • ma w prognoza
 116
Author: f3lix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-11 20:04:21

Lub możesz po prostu obliczyć go za pomocą filtra, oto funkcja, której używam:

ma <- function(x,n=5){filter(x,rep(1/n,n), sides=2)}

 180
Author: Matti Pastell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-01 12:06:50

Stosowanie cumsum powinno być wystarczające i skuteczne. Zakładając, że masz wektor x i chcesz mieć sumę runową n liczb

cx <- c(0,cumsum(x))
rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n

Jak wskazano w komentarzach @ mzuther, zakłada to, że w danych nie ma serwera NAs. aby poradzić sobie z nimi, wymagałoby podzielenia każdego okna przez liczbę wartości innych niż NA. Oto jeden sposób na zrobienie tego, włączając komentarz od @ 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

To nadal ma problem, że jeśli wszystkie wartości w oknie są NAs wtedy będzie podział przez zero błędu.

 24
Author: pipefish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-05 17:29:46

Możesz użyć RcppRoll do bardzo szybkich średnich kroczących napisanych w C++. Wystarczy wywołać funkcję roll_mean. Dokumenty można znaleźć tutaj .

W przeciwnym razie ta (wolniejsza) pętla for powinna zadziałać:

ma <- function(arr, n=15){
  res = arr
  for(i in n:length(arr)){
    res[i] = mean(arr[(i-n):i])
  }
  res
}
 7
Author: cantdutchthis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 05:22:09

Pakiet caTools ma bardzo szybkie zwijanie średnie / min / max / sd i kilka innych funkcji. Pracowałem tylko z runmean i runsd i są one najszybsze z wszystkich innych pakietów wymienionych do tej pory.

 6
Author: eddi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-21 17:11:53

W rzeczywistości RcppRoll jest bardzo dobry.

Kod zamieszczony przez cantdutchthis należy poprawić w czwartej linijce do okna być fixed:

ma <- function(arr, n=15){
  res = arr
  for(i in n:length(arr)){
    res[i] = mean(arr[(i-n+1):i])
  }
  res
}

Inny sposób, który obsługuje missings, jest podany tutaj .

A third way, improving cantdutchthis code to calculate partial average or not, follows:

  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,...)]
  }
}
 6
Author: Rodrigo Remedio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:19

W celu uzupełnienia odpowiedzi cantdutchthis i Rodrigo Remedio ;

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)
 3
Author: Cristóbal Alcázar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 14:29:46

Choć trochę powolny, ale można również użyć zoo:: rollapply do wykonywania obliczeń na macierzach.

reqd_ma <- rollapply(x, FUN = mean, width = n)

Gdzie x jest zbiorem danych, FUN = mean jest funkcją; Można również zmienić ją na min, max, sd itd., a szerokość jest tocznym oknem.

 0
Author: Garima gulati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-11 04:34:26