Aan de slagGa gratis aan de slag

Vector klonen

In tegenstelling tot R gebruikt C++ een systeem van kopiëren door verwijzing. Dat betekent dat als je een variabele kopieert en vervolgens de kopie wijzigt, de wijzigingen ook in het origineel plaatsvinden.

// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
  // Maak een kopie
  NumericVector y = x;
  // Pas de kopie aan
  y[0] = 2;
  // De wijzigingen gebeuren ook in het origineel
  return x[0];
}

Om dit te voorkomen, moet je de functie clone() gebruiken om de onderliggende data van de oorspronkelijke variabele naar de nieuwe variabele te kopiëren. De syntax is y = clone(x). In deze oefening hebben we twee functies voor je gedefinieerd:

  • change_negatives_to_zero(): Neemt een numerieke vector, past deze aan door negatieve getallen te vervangen door nul, en geeft vervolgens zowel de oorspronkelijke vector als de kopie terug.
  • change_negatives_to_zero_with_cloning(): Doet hetzelfde als hierboven, maar kloont de oorspronkelijke vector vóór het aanpassen.

Deze oefening maakt deel uit van de cursus

R-code optimaliseren met Rcpp

Cursus bekijken

Oefeninstructies

  • Maak de functiedefinitie van change_negatives_to_zero() af door the_original gelijk te zetten aan the_copy.
  • Maak de functiedefinitie van change_negatives_to_zero_with_cloning() af door the_copy gelijk te zetten aan de kloon van the_original.
  • Lees de console-uitvoer om de resultaten van elke functie te vergelijken.

Praktische interactieve oefening

Probeer deze oefening eens door deze voorbeeldcode in te vullen.

#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)
*/
Code bewerken en uitvoeren