CommencerCommencer gratuitement

Clonage de vecteurs

Contrairement à R, C++ utilise un système de copie par référence : si vous copiez une variable puis modifiez la copie, les changements s’appliqueront aussi à l’originale.

// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
  // Make a copy
  NumericVector y = x;
  // Modify the copy
  y[0] = 2;
  // The changes also happen in the original
  return x[0];
}

Pour éviter ce comportement, vous devez utiliser la fonction clone() afin de copier les données sous-jacentes de la variable originale dans la nouvelle variable. La syntaxe est y = clone(x). Dans cet exercice, deux fonctions ont été définies pour vous :

  • change_negatives_to_zero() : prend un vecteur numérique, le modifie en remplaçant les valeurs négatives par zéro, puis retourne à la fois le vecteur original et la copie.
  • change_negatives_to_zero_with_cloning() : fait la même chose que ci-dessus, mais clone le vecteur original avant de le modifier.

Cet exercice fait partie du cours

Optimiser du code R avec Rcpp

Afficher le cours

Instructions

  • Complétez la définition de la fonction change_negatives_to_zero() en affectant the_original à the_copy.
  • Complétez la définition de la fonction change_negatives_to_zero_with_cloning() en affectant the_copy au clone de the_original.
  • Lisez le contenu de la console pour comparer la sortie de chaque fonction.

Exercice interactif pratique

Essayez cet exercice en complétant cet exemple de code.

#include 
using namespace Rcpp;

// [[Rcpp::export]]
List change_negatives_to_zero(NumericVector the_original) {
  // Set the copy to the original
  NumericVector the_copy = ___;
  int n = the_original.size();
  for(int i = 0; i < n; i++) {
    if(the_copy[i] < 0) the_copy[i] = 0;
  }
  return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}

// [[Rcpp::export]]
List change_negatives_to_zero_with_cloning(NumericVector the_original) {
  // Clone the original to make the copy
  NumericVector the_copy = ___;
  int n = the_original.size();
  for(int i = 0; i < n; i++) {
    if(the_copy[i] < 0) the_copy[i] = 0;
  }
  return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}

/*** R
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero(x)
# Need to define x again because it's changed now
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero_with_cloning(x)
*/
Modifier et exécuter le code