ÎncepețiÎncepe gratuit

Clonarea vectorilor

Spre deosebire de R, C++ folosește un sistem de copiere prin referință, ceea ce înseamnă că dacă copiezi o variabilă și apoi modifici copia, modificările vor afecta și variabila originală.

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

Pentru a evita acest comportament, trebuie să folosești funcția clone(), care copiază datele din variabila originală într-o variabilă nouă. Sintaxa este y = clone(x). În acest exercițiu, am definit două funcții pentru tine:

  • change_negatives_to_zero(): Primește un vector numeric, îl modifică înlocuind valorile negative cu zero, apoi returnează atât vectorul original, cât și copia.
  • change_negatives_to_zero_with_cloning(): Face același lucru ca mai sus, dar clonează vectorul original înainte de a-l modifica.

Acest exercițiu face parte din cursul

Optimizarea codului R cu Rcpp

Vezi cursul

Instrucțiuni pentru exercițiu

  • Completează definiția funcției change_negatives_to_zero() setând the_copy la valoarea lui the_original.
  • Completează definiția funcției change_negatives_to_zero_with_cloning() setând the_copy la clona lui the_original.
  • Citește conținutul consolei pentru a compara rezultatele celor două funcții.

Exercițiu interactiv practic

Încearcă acest exercițiu completând acest cod de exemplu.

#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)
*/
Editează și rulează codul