Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting an RPy2 ListVector to a Python dictionary

Tags:

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?

like image 682
cbare Avatar asked Jun 10 '14 22:06

cbare


2 Answers

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)} 
like image 117
CT Zhu Avatar answered Nov 02 '22 22:11

CT Zhu


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} 
like image 44
jacobm654321 Avatar answered Nov 03 '22 00:11

jacobm654321