Skip to content

Instantly share code, notes, and snippets.

@lebedov
Created November 1, 2018 17:00
Show Gist options
  • Save lebedov/1c46be79deddcbcb1df7ee1af44db92a to your computer and use it in GitHub Desktop.
Save lebedov/1c46be79deddcbcb1df7ee1af44db92a to your computer and use it in GitHub Desktop.
Recursively convert rpy2 objects to nested Python data structures.
#!/usr/bin/env python3
"""
Recursively convert rpy2 objects to nested Python data structures.
"""
import numpy as np
from rpy2.robjects import default_converter, globalenv, \
NULL, numpy2ri, pandas2ri, ListVector, r
def scalarize(x):
if not np.isscalar(x) and len(x) == 1:
return np.asscalar(x)
else:
return x
converter = default_converter+numpy2ri.converter+pandas2ri.converter
def convert(ri):
"""
Recursively convert rpy2 object to nested Python object.
Objects containing R code (typeof(x) == 'language') are filtered out.
Objects containing R lists with no string tags are converted to Python
lists.
"""
if isinstance(ri, ListVector):
if ri.names == NULL:
result = [convert(tmp[1]) for tmp in ri.items()]
else:
result = {}
for name in ri.names:
globalenv['tmp'] = ri.rx2(name)
if r('typeof(tmp)')[0] != 'language':
result[name] = convert(ri.rx2(name))
return result
else:
return scalarize(converter.ri2py(ri))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment