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조건에서x의i번째 요소가NumericVector의NA인지 확인하세요.- 조건이 참이면, 결과의
i번째 값을 결측이 아닌 값들의 합total_not_na를 결측이 아닌 값의 개수n_not_na로 나눈 값으로 설정하세요. - 그렇지 않다면
total_not_na에x의i번째 요소를 더하고,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
)
*/