I am new to Rcpp and C++ coding in general, so forgive me for asking basic questions. The cpp part of the code is
// test.cpp
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void testRun() {
IntegerVector Grp1 = IntegerVector::create(1,2,3,4);
IntegerVector Grp2 = IntegerVector::create(3,4,5,6);
Rf_PrintValue(Grp1);
Grp1 = Grp2;
Rf_PrintValue(Grp1);
Grp2[3] = Grp2[3]+1;
Rf_PrintValue(Grp1);
}
and when I run testrun(), I get the output
> Rcpp::sourceCpp('test.cpp')
> testRun()
[1] 1 2 3 4
[1] 3 4 5 6
[1] 3 4 5 7
When I assign Gr2
to Gr1
in Gr1 = Gr2
, changing elements in Gr2
after the assignment changes the values in Gr1
as well. Is there a function for IntegerVectors that could do something like Gr1 = copy of Gr2
or should I be using a loop to do that.
Thanks a lot!
Begin Initialize a vector v1 with its elements. Declare another vector v2 and copying elements of first vector to second vector using constructor method and they are deeply copied. Print the elements of v1. Print the elements of v2.
You can't move elements from one vector to another the way you are thinking about; you will always have to erase the element positions from the first vector. If you want to change all the elements from the first vector into the second and vice versa you can use swap. @R.
The simplest solution is to use a copy constructor to initialize the target vector with the copy of all the first vector elements. Then, call the vector::insert function to copy all elements of the second vector. We can also use only vector::insert to copy elements of both vectors into the destination vector.
As hinted in the comment, you could use
Grp1 = clone(Grp2) ;
but this will create a new R object that then get assigned to Grp1
, so you pay for some memory allocation and you discard some memory that could have been used, i.e. more work for the garbage collector down the line.
You could also just reuse the existing memory from Grp1
with std::copy
std::copy( Grp2.begin(), Grp2.end(), Grp1.begin() ) ;
Another way that is perhaps over the top is to use sapply
. Something like this:
auto identity = [](double x){ return x; } ;
Grp1 = sapply( Grp2, identity );
But given Rcpp
does not sapply over lambdas, you'd probably have to define identity
outside your function for this approach to be useable.
inline double identity(double x){
return x ;
}
FWIW, in Rcpp14
or Rcpp11
, you could simply do:
Grp1 = import(Grp2) ;
What is currently happening is a very common error with pointers. Grp1 and Grp2 are pointers, so setting one equal to the other means that they point to the same array (and any changes to one array will affect the other). One solution would be to use a iterator to copy all values over one at a time. This would be done by emptying one IntegerVector by popping all values and then pushing all elements from the other IntegerVector into the emptied IntegerVector.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With