Converting an RPy2 ListVector to a Python dictionary
I think to get a r vector into a dictionary
does not have to be so involving, how about this:
In [290]:dict(zip(a.names, list(a)))Out[290]:{'fizz': <FloatVector - Python:0x08AD50A8 / R:0x10A67DE8>[123.000000], 'foo': <StrVector - Python:0x08AD5030 / R:0x10B72458>['barbat']}In [291]:dict(zip(a.names, map(list,list(a))))Out[291]:{'fizz': [123.0], 'foo': ['barbat']}
And of course, if you don't mind using pandas
, it is even easier. The result will have numpy.array
instead of list
, but that will be OK in most cases:
In [294]:import pandas.rpy.common as comcom.convert_robj(a)Out[294]:{'fizz': [123.0], 'foo': array(['barbat'], dtype=object)}
Simple R list to Python dictionary:
>>> import rpy2.robjects as robjects>>> a = robjects.r('list(foo="barbat", fizz=123)')>>> d = { key : a.rx2(key)[0] for key in a.names }>>> d{'foo': 'barbat', 'fizz': 123.0}
Arbitrary R object to Python object using R RJSONIO JSON serialization/deserialization
On R server: install.packages("RJSONIO", dependencies = TRUE)
>>> ro.r("library(RJSONIO)")<StrVector - Python:0x300b8c0 / R:0x3fbccb0>[str, str, str, ..., str, str, str]>>> import rpy2.robjects as robjects>>> rjson = robjects.r(' toJSON( list(foo="barbat", fizz=123, lst=list(33,"bb")) ) ')>>> pyobj = json.loads( rjson[0] )>>> pyobj{u'lst': [33, u'bb'], u'foo': u'barbat', u'fizz': 123}>>> pyobj['lst'][33, u'bb']>>> pyobj['lst'][0]33>>> pyobj['lst'][1]u'bb'>>> rjson = robjects.r(' toJSON( list(foo="barbat", fizz=123, lst=list( key1=33,key2="bb")) ) ')>>> pyobj = json.loads( rjson[0] )>>> pyobj{u'lst': {u'key2': u'bb', u'key1': 33}, u'foo': u'barbat', u'fizz': 123}
I had the same problem with a deeply nested structure of different rpy2 vector types. I couldn't find a direct answer anywhere on stackoverflow, so here's my solution.Using CT Zhu's answer, I came up with the following code to convert the complete structure to python types recursively.
from collections import OrderedDictimport numpy as npfrom rpy2.robjects.vectors import DataFrame, FloatVector, IntVector, StrVector, ListVector, Matrixdef recurse_r_tree(data): """ step through an R object recursively and convert the types to python types as appropriate. Leaves will be converted to e.g. numpy arrays or lists as appropriate and the whole tree to a dictionary. """ r_dict_types = [DataFrame, ListVector] r_array_types = [FloatVector, IntVector, Matrix] r_list_types = [StrVector] if type(data) in r_dict_types: return OrderedDict(zip(data.names, [recurse_r_tree(elt) for elt in data])) elif type(data) in r_list_types: return [recurse_r_tree(elt) for elt in data] elif type(data) in r_array_types: return np.array(data) else: if hasattr(data, "rclass"): # An unsupported r class raise KeyError('Could not proceed, type {} is not defined' 'to add support for this type, just add it to the imports ' 'and to the appropriate type list above'.format(type(data))) else: return data # We reached the end of recursion