Moyenne reportée
Une autre option que « last observation carried forward » consiste à remplacer les NA par la moyenne de toutes les valeurs précédentes qui ne sont pas NA. On appelle cela la moyenne reportée (mean carried forward). Encore une fois, avec R, il faut choisir entre lisibilité et vitesse. Le code suivant favorise la lisibilité :
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
}
La nature itérative rend la vectorisation difficile. Transformons donc cette fonction en C++. Complétez la définition de na_meancf2(), une traduction C++ de na_meancf1().
Cette activité fait partie du cours
Optimiser le code R avec Rcpp
Instructions de l’exercice
- Dans la condition du
if, vérifiez si le iᵉ élément dexcorrespond à unNAd'unNumericVector. - Si la condition est vraie, définissez le iᵉ résultat comme le total des valeurs non manquantes,
total_not_na, divisé par leur nombre,n_not_na. - Sinon, augmentez
total_not_nadu iᵉ élément dexet ajoutez1àn_not_na.
Exercice interactif pratique
Essayez cet exercice en complétant ce code d’exemple.
#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
)
*/