CommencezCommencez gratuitement

Dernière observation reportée

Lorsque vous avez des données manquantes dans une série chronologique, une technique courante consiste à reprendre la dernière valeur non manquante. On appelle cela la dernière observation reportée (last observation carried forward). Cela s'exprime naturellement avec du code itératif. Voici une implémentation en 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
}

Comme pour les moyennes mobiles, il est vraiment difficile de vectoriser ce code tout en le gardant lisible. Cependant, comme il s'agit simplement d'une boucle for, on peut facilement le traduire en C++.

na_locf1() est fourni dans votre espace de travail. Convertissez-la en C++ et assignez-la à na_locf2().

Cette activité fait partie du cours

Optimiser le code R avec Rcpp

Voir le cours

Instructions de l’exercice

  • Initialisez current à la valeur NA d'un NumericVector.
  • La condition du if doit vérifier si le ie élément de x est un NA de NumericVector.
  • Lorsque cette condition est vraie, affectez current au ie élément de res.
  • Sinon, affectez au ie élément de x la valeur de current.

Exercice interactif pratique

Essayez cet exercice en complétant ce code d’exemple.

#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
  )
*/
Modifier et exécuter le code