Switching between a conversion and a no conversion mode, an operation often present when working with RPy-1.x, is no longer necessary as the R objects can be either passed on to R functions or used in Python.
However, there is a low-level mapping between R and Python objects performed behind the (Python-level) scene, done by the rpy2.rinterface, while an higher-level mapping is done between low-level objects and higher-level objects using the functions:
Those functions can be re-routed to satisfy all requirements, with the easiest option being to write a custom function calling itself the default function when the custom conversion should not apply.
As an example, let’s assume that one want to return atomic values whenever an R numerical vector is of length one. This is only a matter of writing a new function ri2py that handles this, as shown below:
import rpy2.robjects as robjects
def my_ri2py(obj):
res = robjects.default_ri2py(obj)
if isinstance(res, robjects.RVector) and (len(res) == 1):
res = res[0]
return res
robjects.conversion.ri2py = my_ri2py
Once this is done, we can verify immediately that this is working with:
>>> pi = robjects.r.pi
>>> type(pi)
<type 'float'>
>>>
The default behavior can be restored with:
>>> robjects.conversion.ri2py = default_ri2py
The docstrings for default_ri2py(), default_py2ri(), and py2ro() are: