The natural Python equivalent to a named list in R is a dict, but RPy2 gives you a ListVector object.
import rpy2.robjects as robjects a = robjects.r('list(foo="barbat", fizz=123)')
At this point, a is a ListVector object.
<ListVector - Python:0x108f92a28 / R:0x7febcba86ff0> [StrVector, FloatVector] foo: <class 'rpy2.robjects.vectors.StrVector'> <StrVector - Python:0x108f92638 / R:0x7febce0ae0d8> [str] fizz: <class 'rpy2.robjects.vectors.FloatVector'> <FloatVector - Python:0x10ac38fc8 / R:0x7febce0ae108> [123.000000]
What I'd like to have is something I can treat like a normal Python dictionary. My temporary hack-around is this:
def as_dict(vector): """Convert an RPy2 ListVector to a Python dict""" result = {} for i, name in enumerate(vector.names): if isinstance(vector[i], robjects.ListVector): result[name] = as_dict(vector[i]) elif len(vector[i]) == 1: result[name] = vector[i][0] else: result[name] = vector[i] return result as_dict(a) {'foo': 'barbat', 'fizz': 123.0} b = robjects.r('list(foo=list(bar=1, bat=c("one","two")), fizz=c(123,345))') as_dict(b) {'fizz': <FloatVector - Python:0x108f7e950 / R:0x7febcba86b90> [123.000000, 345.000000], 'foo': {'bar': 1.0, 'bat': <StrVector - Python:0x108f7edd0 / R:0x7febcba86ea0> [str, str]}}
So, the question is... Is there a better way or something built into RPy2 that I should be using?
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 com com.convert_robj(a) Out[294]: {'fizz': [123.0], 'foo': array(['barbat'], dtype=object)}
>>> 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}
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}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With