Created
November 1, 2018 17:00
-
-
Save lebedov/1c46be79deddcbcb1df7ee1af44db92a to your computer and use it in GitHub Desktop.
Recursively convert rpy2 objects to nested Python data structures.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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