Kom igångKom igång gratis

Kloning av vektorer

Till skillnad från R använder C++ ett kopiera via referens-system, vilket innebär att om du kopierar en variabel och sedan ändrar kopian, kommer ändringarna även att påverka originalet.

// [[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];
}

För att undvika det här beteendet behöver du använda funktionen clone(), som kopierar den underliggande datan från originalvariabeln till den nya variabeln. Syntaxen är y = clone(x). I den här övningen har vi definierat två funktioner åt dig:

  • change_negatives_to_zero(): Tar en numerisk vektor, modifierar den genom att ersätta negativa tal med noll och returnerar sedan både originalvektorn och kopian.
  • change_negatives_to_zero_with_cloning(): Gör samma sak som ovan, men klonar originalvektorn innan den modifieras.

Den här övningen är en del av kursen

Optimera R-kod med Rcpp

Visa kurs

Övningsinstruktioner

  • Slutför funktionsdefinitionen för change_negatives_to_zero() genom att tilldela the_original till the_copy.
  • Slutför funktionsdefinitionen för change_negatives_to_zero_with_cloning() genom att sätta the_copy till klonen av the_original.
  • Läs konsolutdata och jämför resultatet från de två funktionerna.

Interaktiv övning med praktiskt arbete

Testa den här övningen genom att slutföra den här exempelkoden.

#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)
*/
Redigera och kör kod