Revision: 568
http://rpy.svn.sourceforge.net/rpy/?rev=568&view=rev
Author: lgautier
Date: 2008-07-02 08:04:22 -0700 (Wed, 02 Jul 2008)
Log Message:
-----------
robjects:
- new class RVectorDelegator, to delegate indexing the "R way" (on a
suggestion by Michael Sorich), as well as operators such as __add__,
__mult__, __and__, __or__.
- getNames renamed to getnames
- fix in RS4.__getattr__ (proper wrapping of the object returned)
Modified Paths:
--------------
branches/rpy_nextgen/rpy/robjects/__init__.py
branches/rpy_nextgen/rpy/robjects/tests/testRArray.py
branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
Modified: branches/rpy_nextgen/rpy/robjects/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/__init__.py 2008-07-02 14:57:48 UTC
(rev 567)
+++ branches/rpy_nextgen/rpy/robjects/__init__.py 2008-07-02 15:04:22 UTC
(rev 568)
@@ -123,9 +123,52 @@
"that inherits from rinterface.Sexp" +\
"(not from %s)" %type(value))
super(RObject, self).__setattr__(name, value)
-
+class RVectorDelegator(object):
+ """
+ Delegate operations such as __getitem__, __add__, etc..
+ to an R call of the corresponding function on its parent
+ attribute.
+ This permits a convenient coexistence between
+ operators on Python sequence object with their R conterparts.
+ """
+ def __init__(self, parent):
+ """ The parent in expected to inherit from RVector. """
+ self._parent = parent
+
+ def __getitem__(self, *args, **kwargs):
+ res = self._parent.subset(*args, **kwargs)
+ return res
+
+ def __add__(self, x):
+ res = r.get("+")(self._parent, x)
+ return res
+
+ def __sub__(self, x):
+ res = r.get("-")(self._parent, x)
+ return res
+
+ def __mul__(self, x):
+ res = r.get("*")(self._parent, x)
+ return res
+
+ def __div__(self, x):
+ res = r.get("/")(self._parent, x)
+ return res
+
+ def __divmod__(self, x):
+ res = r.get("%%")(self._parent, x)
+ return res
+
+ def __or__(self, x):
+ res = r.get("|")(self._parent, x)
+ return res
+
+ def __and__(self, x):
+ res = r.get("&")(self._parent, x)
+ return res
+
class RVector(RObjectMixin, rinterface.SexpVector):
""" R vector-like object. Items in those instances can
be accessed with the method "__getitem__" ("[" operator),
@@ -135,6 +178,7 @@
if not isinstance(o, rinterface.SexpVector):
o = py2ri(o)
super(RVector, self).__init__(o)
+ self.r = RVectorDelegator(self)
def subset(self, *args, **kwargs):
@@ -160,11 +204,16 @@
def assign(self, *args):
#FIXME: value must be the last argument, but this can be
# challenging in since python kwargs do not enforce any order
+ #(an ordered dictionary class will therefore be implemented)
args = [py2ro(x) for x in args]
res = r["[<-"](*([self, ] + [x for x in args]))
return res
+ def __add__(self, x):
+ res = r.get("c")(self, x)
+ return res
+
def __getitem__(self, i):
res = super(RVector, self).__getitem__(i)
if isinstance(res, rinterface.Sexp):
@@ -175,39 +224,11 @@
value = py2ri(value)
res = super(RVector, self).__setitem__(i, value)
- def __add__(self, x):
- res = r.get("+")(self, x)
- return res
-
- def __sub__(self, x):
- res = r.get("-")(self, x)
- return res
-
- def __mul__(self, x):
- res = r.get("*")(self, x)
- return res
-
- def __div__(self, x):
- res = r.get("/")(self, x)
- return res
-
- def __divmod__(self, x):
- res = r.get("%%")(self, x)
- return res
-
- def __or__(self, x):
- res = r.get("|")(self, x)
- return res
-
- def __and__(self, x):
- res = r.get("&")(self, x)
- return res
-
- def getNames(self):
+ def getnames(self):
res = r.names(self)
return res
- def setNames(self, value):
+ def setnames(self, value):
""" Return a vector of names
(like the R function 'names' does it)."""
@@ -233,7 +254,7 @@
value = py2ro(value)
res = r["dim<-"](value)
- def getNames(self):
+ def getnames(self):
""" Return a list of name vectors
(like the R function 'dimnames' does it)."""
@@ -301,6 +322,7 @@
def __getattr__(self, attr):
res = self.do_slot(attr)
+ res = ri2py(res)
return res
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRArray.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRArray.py 2008-07-02
14:57:48 UTC (rev 567)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRArray.py 2008-07-02
15:04:22 UTC (rev 568)
@@ -26,7 +26,7 @@
m = robjects.r.matrix(1, nrow=3, ncol=2,
dimnames = dimnames)
a = robjects.RArray(m)
- res = a.getNames()
+ res = a.getnames()
r_identical = robjects.r.identical
self.assertTrue(r_identical(dimnames[0], res[0]))
self.assertTrue(r_identical(dimnames[1], res[1]))
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRVector.py 2008-07-02
14:57:48 UTC (rev 567)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRVector.py 2008-07-02
15:04:22 UTC (rev 568)
@@ -20,17 +20,33 @@
del(ri_v)
self.assertEquals(ri.INTSXP, ro_v.typeof())
-
- def testOperators(self):
+
+ def testAddOperators(self):
seq_R = robjects.r["seq"]
+ mySeqA = seq_R(0, 3)
+ mySeqB = seq_R(5, 7)
+ mySeqAdd = mySeqA + mySeqB
+
+ self.assertEquals(len(mySeqA)+len(mySeqB), len(mySeqAdd))
+
+ for i, li in enumerate(mySeqA):
+ self.assertEquals(li, mySeqAdd[i])
+ for j, li in enumerate(mySeqB):
+ self.assertEquals(li, mySeqAdd[i+j+1])
+
+ def testRAddOperators(self):
+ seq_R = robjects.r["seq"]
mySeq = seq_R(0, 10)
- mySeqAdd = mySeq + 2
+ mySeqAdd = mySeq.r + 2
for i, li in enumerate(mySeq):
- self.assertEquals(i + 2, mySeqAdd[i])
+ self.assertEquals(li + 2, mySeqAdd[i])
- mySeqAdd = mySeq + mySeq
+ def testRMultOperators(self):
+ seq_R = robjects.r["seq"]
+ mySeq = seq_R(0, 10)
+ mySeqAdd = mySeq.r + mySeq
for i, li in enumerate(mySeq):
- self.assertEquals(mySeq[i] * 2, mySeqAdd[i])
+ self.assertEquals(li * 2, mySeqAdd[i])
def testSubsetByIndex(self):
@@ -43,6 +59,11 @@
for i, si in enumerate(myIndex):
self.assertEquals(mySeq[si-1], mySubset[i])
+ # same with the delegator
+ mySubset = mySeq.r[myIndex]
+ for i, si in enumerate(myIndex):
+ self.assertEquals(mySeq[si-1], mySubset[i])
+
def testSubsetByName(self):
seq_R = robjects.baseNameSpaceEnv["seq"]
mySeq = seq_R(0, 25)
@@ -122,17 +143,17 @@
r_names = robjects.baseNameSpaceEnv["c"](*v_names)
vec = robjects.baseNameSpaceEnv["names<-"](vec, r_names)
for i in xrange(len(vec)):
- self.assertEquals(v_names[i], vec.getNames()[i])
+ self.assertEquals(v_names[i], vec.getnames()[i])
- vec.getNames()[0] = 'x'
+ vec.getnames()[0] = 'x'
def testSetNames(self):
vec = robjects.RVector(array.array('i', [1,2,3]))
names = ['x', 'y', 'z']
#FIXME: simplify this
- vec = vec.setNames(names)
+ vec = vec.setnames(names)
for i in xrange(len(vec)):
- self.assertEquals(names[i], vec.getNames()[i])
+ self.assertEquals(names[i], vec.getnames()[i])
def suite():
suite = unittest.TestLoader().loadTestsFromTestCase(RVectorTestCase)
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
rpy-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list