LoslegenKostenlos loslegen

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

Kurs anzeigen

Anleitung zur Übung

  • Vervollständige die Funktionsdefinition von change_negatives_to_zero(), indem du the_copy auf the_original setzt.
  • Vervollständige die Funktionsdefinition von change_negatives_to_zero_with_cloning(), indem du the_copy auf den Klon von the_original setzt.
  • 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)
*/
Code bearbeiten und ausführen