Giữ nguyên quan sát cuối cùng
Khi bạn có dữ liệu bị thiếu trong chuỗi thời gian, một kỹ thuật phổ biến là lấy giá trị hợp lệ gần nhất trước đó để điền vào. Cách làm này gọi là last observation carried forward (giữ nguyên quan sát cuối cùng). Cách diễn đạt tự nhiên là dùng mã lặp. Dưới đây là một triển khai bằng R:
na_locf1 <- function(x) {
current <- NA
res <- x
for(i in seq_along(x)) {
if(is.na(x[i])) {
# Replace with current
res[i] <- current
} else {
# Set current
current <- x[i]
}
}
res
}
Giống như rolling means, rất khó để vector hóa đoạn mã này mà vẫn giữ được tính dễ đọc. Tuy nhiên, vì đây chỉ là một vòng lặp for, nên có thể dễ dàng dịch sang C++.
na_locf1() đã có sẵn trong không gian làm việc của bạn. Hãy chuyển nó sang C++ và gán cho na_locf2().
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
Hướng dẫn bài tập
- Khởi tạo
currentbằng giá trịNAcủaNumericVector. - Điều kiện
ifcần kiểm tra xem phần tử thứicủaxcó phải làNAcủaNumericVectorhay không. - Khi điều kiện đó đúng, gán phần tử thứ
icủaresbằngcurrent. - Ngược lại, gán
currentbằng phần tử thứicủax.
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_locf2(NumericVector x) {
// Initialize to NA
double current = ___::___();
int n = x.size();
NumericVector res = clone(x);
for(int i = 0; i < n; i++) {
// If ith value of x is NA
if(___::___(___)) {
// Set ith result as current
res[i] = ___;
} else {
// Set current as ith value of x
current = ___;
}
}
return res ;
}
/*** R
library(microbenchmark)
set.seed(42)
x <- rnorm(1e5)
# Sprinkle some NA into x
x[sample(1e5, 100)] <- NA
microbenchmark(
na_locf1(x),
na_locf2(x),
times = 5
)
*/