Hi All,
i have a problem in understanding what the assignment operator '<-' really is
doing.
If i create two numeric arrays in R and copy one into the other with '<-' and
afterwards change one array by calling a C function, both arrays are changed!
The problem I am facing can easily be seen in the following example:
(The following R code and the C function is attached and the C function can be
compiled with R CMD SHLIB test.c.)
First include the c function:
dyn.load("test.so")
Let's start with 2 arrays:
a <- rep(0, 5)
b <- rep(1, 5)
Now print the memory addresses:
print(sprintf("a: %s b: %s", tracemem(a), tracemem(b) ))
[1] "a: <0x29d34e0> b: <0x29946e0>"
oky, they are different! Now copy a into b and print again the addresses:
b <- a
print(sprintf("a: %s b: %s", tracemem(a), tracemem(b) ))
[1] "a: <0x29d34e0> b: <0x29d34e0>"
Ugh they are the same. If I now call my C function, which writes 0,1,2,3,4 into
an array of 5 doubles,
of course 'both' arrays are changed:
.Call("test", b)
print( cbind(a,b) )
a b
[1,] 0 0
[2,] 1 1
[3,] 2 2
[4,] 3 3
[5,] 4 4
If i just change one element of b instead of calling the c function, then a
full copy of b is made:
a <- rep(0, 5)
b <- rep(1, 5)
print(sprintf("a: %s b: %s", tracemem(a), tracemem(b) ))
[1] "a: <0x2994b58> b: <0x2912ff8>"
b <- a
print(sprintf("a: %s b: %s", tracemem(a), tracemem(b) ))
[1] "a: <0x2994b58> b: <0x2994b58>"
b[1] <- 5
print(sprintf("a: %s b: %s", tracemem(a), tracemem(b) ))
"a: <0x2994b58> b: <0x29134d8>"
print( cbind(a,b) )
a b
[1,] 0 5
[2,] 0 0
[3,] 0 0
[4,] 0 0
[5,] 0 0
So what is happening here? What is the 'right' way to ensure a deep copy before
using Call?
I am currently using a for loop and copy every single element.
Thanks!
// Compile with
// R CMD SHLIB test.c -Wall -Wextra
#include<R.h>
#include<Rdefines.h>
SEXP test( SEXP c )
{
PROTECT( c = AS_NUMERIC(c) );
double* _c = REAL(c);
int i;
for(i=0; i<5; i++)
_c[i] = (double)i;
UNPROTECT(1);
return R_NilValue;
}
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel