시작하기무료로 시작하기

롤링 평균

롤링 평균(이동 평균이라고도 함)은 시계열 분석에서 잡음을 완화하는 데 사용돼요. 각 시점의 값은 주변 시점들(즉, window)의 평균으로 대체됩니다.

이 기능을 자연스럽게 구현하는 방법은 다음과 같아요.

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
}

이 코드는 mean()을 여러 번 호출하므로 비효율적이에요. 한 가지 해결책은 total 변수를 사용해, 루프의 각 반복에서 더 이상 필요 없는 원소를 빼고 새로운 원소를 더하는 방식이에요.

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
}

어느 쪽이든, 벡터화된 코드보다 루프를 쓰는 방식이 더 자연스럽게 느껴질 수 있는데, 이는 성능을 떨어뜨릴 수 있어요. 위의 두 버전은 각자 비효율적인 부분이 있습니다. 다음 연습 문제에서 C++ 버전으로 가기 전에, 먼저 벡터화를 활용한 버전을 작성해 보죠. 작업 공간에는 rollmean1(), rollmean2(), 그리고 임의 벡터 x가 준비되어 있어요. 이제 rollmean3()의 함수 정의를 완성하고, 이 함수들의 성능을 벤치마크해 보겠습니다.

이 연습은 강의의 일부입니다

Rcpp로 R 코드 최적화하기

강의 보기

실습형 인터랙티브 연습

이 예제를 이 샘플 코드를 완성하여 풀어보세요.

# 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
  )
}
코드 편집 및 실행