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
Oefeninstructies
- Maak de functiedefinitie van
change_negatives_to_zero()af doorthe_originalgelijk te zetten aanthe_copy. - Maak de functiedefinitie van
change_negatives_to_zero_with_cloning()af doorthe_copygelijk te zetten aan de kloon vanthe_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)
*/