Vektoren klonen
Anders als R verwendet C++ ein System der Kopie per Referenz. Das heißt: Wenn du eine Variable kopierst und dann die Kopie änderst, wirken sich die Änderungen auch auf das Original aus.
// [[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];
}
Um dieses Verhalten zu vermeiden, musst du die Funktion clone() verwenden, um die zugrunde liegenden Daten aus der ursprünglichen Variable in die neue Variable zu kopieren. Die Syntax ist y = clone(x).
In dieser Übung haben wir zwei Funktionen für dich definiert:
change_negatives_to_zero(): Nimmt einen numerischen Vektor, ersetzt negative Zahlen durch Null und gibt dann sowohl den ursprünglichen Vektor als auch die Kopie zurück.change_negatives_to_zero_with_cloning(): Macht dasselbe wie oben, klont aber den ursprünglichen Vektor, bevor er geändert wird.
Diese Übung ist Teil des Kurses
R-Code mit Rcpp optimieren
Anleitung zur Übung
- Vervollständige die Funktionsdefinition von
change_negatives_to_zero(), indem duthe_copyaufthe_originalsetzt. - Vervollständige die Funktionsdefinition von
change_negatives_to_zero_with_cloning(), indem duthe_copyauf den Klon vonthe_originalsetzt. - Sieh dir die Ausgaben in der Konsole an, um die Ergebnisse der beiden Funktionen zu vergleichen.
Interaktive Übung
Vervollständige den Beispielcode, um diese Übung erfolgreich abzuschließen.
#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)
*/