Bắt đầu ngayBắt đầu miễn phí

Điền giá trị trung bình (mean carried forward)

Một cách khác thay cho phương pháp giữ nguyên quan sát cuối cùng (last observation carried forward) là thay các NA bằng giá trị trung bình của tất cả các giá trị trước đó không phải NA. Cách này gọi là mean carried forward. Một lần nữa, trong R bạn phải chọn giữa khả năng đọc và tốc độ. Đoạn dưới đây ưu tiên khả năng đọc:

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
}

Tính lặp khiến việc vector hóa khá khó, nên thay vào đó, hãy chuyển nó sang C++. Hoàn thiện định nghĩa na_meancf2(), bản C++ của na_meancf1().

Bài tập này là một phần của khóa học

Tối ưu hóa mã R với Rcpp

Xem khóa học

Hướng dẫn bài tập

  • Trong điều kiện if, kiểm tra xem phần tử thứ i của x có phải là NA của NumericVector hay không.
  • Nếu điều kiện đúng, gán kết quả thứ i bằng tổng các giá trị không khuyết total_not_na chia cho số lượng giá trị không khuyết n_not_na.
  • Ngược lại, tăng total_not_na bằng phần tử thứ i của x, và cộng 1 vào n_not_na.

Bài tập tương tác thực hành trực tiếp

Hãy thử làm bài tập này bằng cách hoàn thành đoạn mã mẫu này.

#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
  )
*/
Chỉnh sửa và Chạy Mã