시작하기무료로 시작하기

이동 평균(rolling mean) 계산(C++)

벡터화한 이동 평균 함수 rollmean3()는 성능은 좋았지만 가독성이 매우 떨어졌어요. 이 코드가 이동 평균을 계산한다는 사실을 파악하기 어렵기 때문에 디버깅과 유지 보수가 힘들어집니다.

두 번째 버전인 rollmean2()는 더 느리지만 읽기가 쉬웠죠. 이를 C++로 옮기면, 읽기 쉬우면서도 빠른 성능을 기대할 수 있습니다.

rollmean2()는 작업 공간에 정의되어 있으니, 동작을 다시 확인하려면 정의를 출력해 보세요. 이제 rollmean2()를 C++로 옮겨 rollmean4()에 할당해 보겠습니다.

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

Rcpp로 R 코드 최적화하기

강의 보기

연습 안내

  • res를 길이가 n이고 값이 NumericVectorget_na() 메서드로 주어지는 NumericVector로 설정하세요.
  • totalx의 처음 window개 값의 합으로 계산하세요.
  • 인덱스 window - 1에서의 평균을 합계를 윈도 크기(window)로 나눈 값으로 계산하세요.
  • 두 번째 루프에서는 합계를 업데이트할 때 xi - window번째 요소를 빼고 i번째 요소를 더하세요.

실습형 인터랙티브 연습

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

#include 
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector rollmean4(NumericVector x, int window) {
  int n = x.size();
  
  // Set res as a NumericVector of NAs with length n
  NumericVector res(___, ___::___());
  
  // Sum the first window worth of values of x
  double total = 0.0;
  for(int i = 0; i < window; i++) {
    total += ___;
  }
  
  // Treat the first case seperately
  res[window - 1] = ___ / window;
  
  // Iteratively update the total and recalculate the mean 
  for(int i = window; i < n; i++) {
    // Remove the (i - window)th case, and add the ith case
    total += - ___ + ___;
    // Calculate the mean at the ith position
    res[i] = total / window;
  }
  
  return res;  
}

/*** R
   # Compare rollmean2, rollmean3 and rollmean4   
   set.seed(42)
   x <- rnorm(1e4)
   microbenchmark( 
    rollmean2(x, 4), 
    rollmean3(x, 4), 
    rollmean4(x, 4), 
    times = 5
   )   
*/
코드 편집 및 실행