Przenoszenie ostatniej zaobserwowanej wartości
Gdy w szeregu czasowym występują brakujące dane, jedną z popularnych technik jest przenoszenie ostatniej dostępnej wartości. Podejście to nosi nazwę last observation carried forward. Dobrze nadaje się do implementacji z użyciem kodu iteracyjnego. Oto implementacja w 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
}
Podobnie jak w przypadku średnich kroczących, wektoryzacja tego kodu jest bardzo trudna bez pogorszenia czytelności. Ponieważ jednak mamy tu do czynienia z prostą pętlą for, można ją łatwo przepisać do C++.
Funkcja na_locf1() jest dostępna w twoim środowisku. Przepisz ją do C++ i przypisz do na_locf2().
To ćwiczenie jest częścią kursu
Optymalizacja kodu R za pomocą Rcpp
Instrukcje do ćwiczenia
- Zainicjalizuj zmienną
currentwartościąNAdla typuNumericVector. - Warunek
ifpowinien sprawdzać, czyi-ty element wektoraxjest wartościąNAtypuNumericVector. - Jeśli warunek jest spełniony, przypisz
i-temu elementowi wektorareswartośćcurrent. - W przeciwnym razie przypisz
currentwartośći-tego elementu wektorax.
Interaktywne ćwiczenie praktyczne
Spróbuj tego ćwiczenia, uzupełniając ten przykładowy kod.
#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
)
*/