Ryan Thompson Ryan Thompson - 3 months ago 17
R Question

How to use R's assignment methods in rpy2?

I'm working with rpy2, and I need to use an assignment method on an R object. For example, starting with this object:

# Python code
from rpy2.robjects import r
myvar = r('c(a=1,b=2,c=3)')


suppose that I want to assign to
names(myvar)
. (Note: Ignore the fact that rpy2 provides an alternate way to access names via
myvar.names
. This only works for names, not arbitrary assignment methods.) In R, I would do:

# R code
names(myvar) <- c("x", "y", "z")


However, this won't work in Python:

# Python code
> names(myvar) = ['x', 'y', 'z']
In [62]: names(myvar) = ['x', 'y', 'z']
File "<ipython-input-62-aa3f7998cdcb>", line 1
names(myvar) = ['x', 'y', 'z']
^
SyntaxError: can't assign to function call


Of course, I can run arbitrary code via rpy2's string eval:

# Python code
r('''names(myvar) <- c("x", "y", "z")''')


but interpolating values into a string to be evaluated doesn't sound fun or safe. So is there a way to safely do the equivalent of
method(object) <- value
through rpy2?

Answer

In R, "setter" functions follow a naming convention that makes the name of the "getter" followed by <-. For example, when doing

names(myvar) <- c("x", "y", "z")

the following is happening:

myvar <- "names<-"(names(myvar), c("x","y","z"))

If we break it down:

> myvar = c(a=1,b=2,c=3)
> # call the assignment function "names<-"    
> "names<-"(names(myvar), c("x","y","z"))   
  x   y   z  
"a" "b" "c"
> # note that the function does not have side effects: a copy
> # of objects with the new names is returned 
> myvar   
a b c       
1 2 3
> # to "replace" the names in myvar:    
> myvar <- "names<-"(names(myvar), c("x","y","z")) 

Doing something like method(object) <- value from rpy2 is straightforward. The python code is looking like:

set_method = r("method<-")
my_object = set_method(my_object, value)
Comments