Last observation carried forward
Als je missende waarden hebt in een tijdreeks, is een veelgebruikte techniek om de laatste niet-missende waarde door te trekken. Dit heet last observation carried forward. Dit laat zich natuurlijk uitdrukken met iteratieve code. Hier is een implementatie in 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
}
Net als bij rollende gemiddelden is het erg lastig om deze code te vectoriseren en toch leesbaar te houden. Maar omdat dit slechts een for-lus is, kun je het eenvoudig naar C++ vertalen.
na_locf1() is beschikbaar in je werkruimte. Zet het om naar C++ en ken het toe aan na_locf2().
Deze oefening maakt deel uit van de cursus
R-code optimaliseren met Rcpp
Oefeninstructies
- Initialiseer
currentmet deNA-waarde van deNumericVector. - De
if-voorwaarde moet controleren of heti-de element vanxeenNAvanNumericVectoris. - Als die voorwaarde waar is, zet dan het
i-de element vanresopcurrent. - Anders zet je
currentop heti-de element vanx.
Praktische interactieve oefening
Probeer deze oefening eens door deze voorbeeldcode in te vullen.
#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
)
*/