IniziaInizia gratis

Clonazione di vettori

Diversamente da R, C++ usa un sistema di copia per riferimento, il che significa che se copi una variabile e poi modifichi la copia, le modifiche avverranno anche nell'originale.

// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
  // Crea una copia
  NumericVector y = x;
  // Modifica la copia
  y[0] = 2;
  // Le modifiche avvengono anche nell'originale
  return x[0];
}

Per evitare questo comportamento, devi usare la funzione clone() per copiare i dati sottostanti dalla variabile originale in quella nuova. La sintassi è y = clone(x). In questo esercizio, abbiamo definito per te due funzioni:

  • change_negatives_to_zero(): prende un vettore numerico, lo modifica sostituendo i numeri negativi con zero, quindi restituisce sia il vettore originale sia la copia.
  • change_negatives_to_zero_with_cloning(): fa la stessa cosa di sopra, ma clona il vettore originale prima di modificarlo.

Questo esercizio fa parte del corso

Ottimizzare il codice R con Rcpp

Visualizza il corso

Istruzioni dell'esercizio

  • Completa la definizione della funzione change_negatives_to_zero() impostando the_copy uguale a the_original.
  • Completa la definizione della funzione change_negatives_to_zero_with_cloning() impostando the_copy uguale al clone di the_original.
  • Leggi i contenuti della console per confrontare l'output di ciascuna funzione.

Esercizio pratico interattivo

Prova a risolvere questo esercizio completando il codice di esempio.

#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)
*/
Modifica ed esegui il codice