Vector cloning
Unlike R, C++ uses a copy by reference system, meaning that if you copy a variable then make changes to the copy, the changes will also take place in the 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];
}
To prevent this behavior, you have to use the clone()
function to copy the underlying data from the original variable into the new variable. The syntax is y = clone(x)
.
In this exercise, we have defined two functions for you:
change_negatives_to_zero()
: Takes a numeric vector, modifies by replacing negative numbers with zero, then returns both the original vector and the copy.change_negatives_to_zero_with_cloning()
: Does the same thing as above, but clones the original vector before modifying it.
This exercise is part of the course
Optimizing R Code with Rcpp
Exercise instructions
- Complete the function definition of
change_negatives_to_zero()
by settingthe_original
tothe_copy
. - Complete the function definition of
change_negatives_to_zero_with_cloning()
by settingthe_copy
to the clone ofthe_original
. - Read the contents of the console to compare the output of each function.
Hands-on interactive exercise
Have a go at this exercise by completing this sample code.
#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)
*/