tags:

views:

397

answers:

5

Hello,

After installing RPy2 from

http://rpy.sourceforge.net/rpy2.html

I'm trying to use it in Python 2.6 IDLE but I'm getting this error:

>>> import rpy2.robjects as robjects
>>> robjects.r['pi']

<RVector - Python:0x0121D8F0 / R:0x022A1760>

What I'm doing wrong?

+1  A: 

In the Python interactive interpreter if an expression returns a value then that value is automatically printed. For example if you create a dictionary and extract a value from it the value is automatically printed, but if this was in an executing script this would not be the case. Look at the following simple example this is not an error but simply python printing the result of the expression:

>>> mymap = {"a":23}
>>> mymap["a"]
23

The same code in a python script would produce no output at all.

In your code you are accessing a map like structure with the code:

>>> robjects.r['pi']

This is returning some R2Py object for which the default string representation is: <RVector - Python:0x0121D8F0 / R:0x022A1760>

If you changed the code to something like:

pi = robjects.r['pi']

you would see no output but the result of the call (a vector) will be assigned to the variable pi and be available for you to use.

Looking at the R2Py documentation It seems many of the objects are by default printed as a type in <> brackets and some memory address information.

Tendayi Mawushe
+3  A: 

Have you tried looking at the vector that's returned?

 >>> pi = robjects.r['pi']
 >>> pi[0]
 3.14159265358979
Shane
+4  A: 

To expand on Shane's answer. rpy2 uses the following Python objects to represent the basic R types:

  • RVector: R scalars and vectors, R Lists are represented as RVectors with names, see below
  • RArray: an R matrix, essentially the RVector with a dimension
  • RDataFrame: an R data.frame

To coerce back to basic Python types look here.

As an example, I use this to convert an R List to a python dict:

rList = ro.r('''list(name1=1,name2=c(1,2,3))''')
pyDict = {}
for name,value in zip([i for i in rList.getnames()],[i for i in rList]):
    if len(value) == 1: pyDict[name] = value[0]
    else: pyDict[name] = [i for i in value]
Mark
A: 

This is not an error, it's simply the 'repr' of the returned robject:

>>> r['pi']
<RVector - Python:0x2c14bd8 / R:0x3719538>
>>> repr(r['pi'])
'<RVector - Python:0x4b77908 / R:0x3719538>'
>>> str(r['pi'])
'[1] 3.141593'
>>> print r['pi']
[1] 3.141593

You can get the value of 'pi' accessing it by index

>>> r['pi'][0]
3.1415926535897931

To access element of named lists (the 'object$attribute' R syntax) I use

>>> l = r.list(a=r.c(1,2,3), b=r.c(4,5,6))
>>> print l
$a
[1] 1 2 3

$b
[1] 4 5 6

>>> print dict(zip(l.names, l))['a']
[1] 1 2 3

but I think there must be a better solution...

naufraghi
A: 

I found this as the only sensible, short discussion of how to go back and forth from R objects and python. naufraghi's solution prompted the following approach to converting a data.frame, which retains the nicer slicing capabilities of the dataframe:

In [69]: import numpy as np

In [70]: import rpy2.robjects as ro

In [71]: df = ro.r['data.frame'](a=r.c(1,2,3), b=r.c(4.0,5.0,6.3))

In [72]: df
Out[72]: <RDataFrame - Python:0x5492200 / R:0x4d00a28>

In [73]: print(df)
  a   b
1 1 4.0
2 2 5.0
3 3 6.3

In [74]: recdf = np.rec.fromarrays(df, names=tuple(df.names))

In [75]: recdf
Out[75]: 
rec.array([(1, 4.0), (2, 5.0), (3, 6.2999999999999998)], 
      dtype=[('a', '<i4'), ('b', '<f8')])

Seems a bit off-topic at this point, but I'm not sure what the appropriate procedure would be to capture this question & answer of mine!

Dav Clark
Nice use of fromarrays(). This will be part of the automagic rpy/numpy conversion module.
lgautier