시작하기무료로 시작하기

Mean carried forward

마지막 관측값 보간(LOCF)의 다른 방법으로, NA를 이전의 결측이 아닌 값들의 평균으로 대체할 수 있어요. 이를 mean carried forward라고 합니다. 여기서도 R에서는 가독성과 속도 사이에서 선택해야 해요. 아래 코드는 가독성을 위해 작성된 버전입니다:

na_meancf1 <- function(x) {
  total_not_na <- 0
  n_not_na <- 0
  res <- x
  for(i in seq_along(x)) {
    if(is.na(x[i])) {
      res[i] <- total_not_na / n_not_na
    } else {
      total_not_na <- total_not_na + x[i]
      n_not_na <- n_not_na + 1
    }
  }
  res
}

반복 계산의 특성 때문에 벡터화가 까다롭습니다. 대신 C++로 변환해 보죠. na_meancf1()을 C++로 옮긴 na_meancf2() 정의를 완성하세요.

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

Rcpp로 R 코드 최적화하기

강의 보기

연습 안내

  • if 조건에서 xi번째 요소가 NumericVectorNA인지 확인하세요.
  • 조건이 참이면, 결과의 i번째 값을 결측이 아닌 값들의 합 total_not_na를 결측이 아닌 값의 개수 n_not_na로 나눈 값으로 설정하세요.
  • 그렇지 않다면 total_not_naxi번째 요소를 더하고, n_not_na에는 1을 더하세요.

실습형 인터랙티브 연습

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

#include 
using namespace Rcpp; 

// [[Rcpp::export]]
NumericVector na_meancf2(NumericVector x) {
  double total_not_na = 0.0;
  double n_not_na = 0.0;
  NumericVector res = clone(x);
  
  int n = x.size();
  for(int i = 0; i < n; i++) {
    // If ith value of x is NA
    if(___) {
      // Set the ith result to the total of non-missing values 
      // divided by the number of non-missing values
      res[i] = ___ / ___;
    } else {
      // Add the ith value of x to the total of non-missing values
      ___;
      // Add 1 to the number of non-missing values
      ___;
    }
  }  
  return res;
}

/*** R
  library(microbenchmark)
  set.seed(42)
  x <- rnorm(1e5)
  x[sample(1e5, 100)] <- NA  
  microbenchmark( 
    na_meancf1(x), 
    na_meancf2(x), 
    times = 5
  )
*/
코드 편집 및 실행