Zacznij terazZacznij za darmo

Kroczące średnie

Kroczące średnie (ang. rolling means, nazywane też średnimi ruchomymi) są stosowane w analizie szeregów czasowych do wygładzania szumu. Wartość w każdym punkcie czasowym zastępowana jest średnią wartości z sąsiednich punktów (tzw. okno).

Naturalny sposób zapisu tej funkcji wygląda tak:

rollmean1 <- function(x, window = 3) {
  n <- length(x)
  res <- rep(NA, n)
  for(i in seq(window, n)) {
    res[i] <- mean(x[seq(i - window + 1, i)])
  }
  res
}

Ta wersja wielokrotnie wywołuje mean(), co jest nieefektywne. Jedno z rozwiązań polega na użyciu zmiennej total — w każdej iteracji pętli odejmujesz element, który nie jest już potrzebny, i dodajesz nowy.

rollmean2 <- function(x, window = 3){
  n <- length(x)
  res <- rep(NA, n)
  total <- sum(head(x, window))
  res[window] <- total / window
  for(i in seq(window + 1, n)) {
    total <- total + x[i] - x[i - window]
    res[i] <- total / window
  }
  res
}

W obu przypadkach kod pętlowy jest znacznie bardziej naturalny niż wektoryzacja, co może obniżać wydajność. Obie powyższe wersje są nieefektywne — każda na swój sposób. Zanim w kolejnym ćwiczeniu napiszesz wersję w C++, stwórz wariant wykorzystujący wektoryzację. W obszarze roboczym dostępne są funkcje rollmean1(), rollmean2() oraz losowy wektor x. Uzupełnij definicję funkcji rollmean3() i porównaj wydajność wszystkich trzech funkcji.

To ćwiczenie jest częścią kursu

Optymalizacja kodu R za pomocą Rcpp

Zobacz kurs

Interaktywne ćwiczenie praktyczne

Spróbuj tego ćwiczenia, uzupełniając ten przykładowy kod.

# Complete the definition of rollmean3()
rollmean3 <- function(x, window = 3) {
  # Add the first window elements of x
  initial_total <- ___(head(x, window))

  # The elements to add at each iteration    
  lasts <- tail(x, - window)
  
  # The elements to remove
  firsts <- head(x, - window)

  # Take the initial total and add the 
  # cumulative sum of lasts minus firsts
  other_totals <- ___ + ___(___ - firsts)

  # Build the output vector 
  c(
    rep(NA, window - 1), # leading NA
    initial_total / ___, # initial mean
    other_totals / ___   # other means
  )
}
Edytuj i uruchom kod