Revision: 555
http://rpy.svn.sourceforge.net/rpy/?rev=555&view=rev
Author: lgautier
Date: 2008-06-08 06:28:27 -0700 (Sun, 08 Jun 2008)
Log Message:
-----------
rinterface:
- fixed R console callback function-defined
- minor code cleanup
robjects:
- function seq2vec to conver list or tuples into vector
- split unit tests
demos:
- catch errors when running R code
doc:
- more indexes
Modified Paths:
--------------
branches/rpy_nextgen/demos/radmin.py
branches/rpy_nextgen/doc/source/rinterface.rst
branches/rpy_nextgen/doc/source/robjects.rst
branches/rpy_nextgen/rpy/rinterface/rinterface.c
branches/rpy_nextgen/rpy/rinterface/tests/test_EmbeddedR.py
branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
branches/rpy_nextgen/rpy/rpy_classic.py
Modified: branches/rpy_nextgen/demos/radmin.py
===================================================================
--- branches/rpy_nextgen/demos/radmin.py 2008-06-08 08:22:28 UTC (rev
554)
+++ branches/rpy_nextgen/demos/radmin.py 2008-06-08 13:28:27 UTC (rev
555)
@@ -457,7 +457,7 @@
def actionKeyPress(self, view, event):
pass
- def append(self, text, tag):
+ def append(self, text, tag="input"):
tag = self.tag_table.lookup(tag)
buffer = self._buffer
end_iter = buffer.get_end_iter()
@@ -473,8 +473,18 @@
stop_iter = buffer.get_iter_at_offset(buffer.get_char_count())
rcode = buffer.get_text(start_iter, stop_iter)
- res = robjects.r(rcode)
-
+ rbuf = []
+ def f(x):
+ rbuf.append(x)
+
+ robjects.rinterface.setWriteConsole(f)
+
+ try:
+ res = robjects.r(rcode)
+ except robjects.rinterface.RRuntimeError, rre:
+ res = str(rre)
+
+ #self.append(str.join('', rbuf), "output")
self.append(str(res), "output")
self.append("\n> ", "input")
Modified: branches/rpy_nextgen/doc/source/rinterface.rst
===================================================================
--- branches/rpy_nextgen/doc/source/rinterface.rst 2008-06-08 08:22:28 UTC
(rev 554)
+++ branches/rpy_nextgen/doc/source/rinterface.rst 2008-06-08 13:28:27 UTC
(rev 555)
@@ -140,6 +140,7 @@
.. index::
single: SexpVector
+ single: rinterface; SexpVector
:class:`SexpVector`
===================
@@ -202,7 +203,7 @@
.. index::
- single: numpy
+ pair: SexpVector; numpy
Numpy
-----
@@ -228,6 +229,7 @@
.. index::
single: SexpEnvironment
+ single: rinterface; SexpEnvironment
:class:`SexpEnvironment`
========================
@@ -288,6 +290,8 @@
.. index::
single: closure
+ single: SexpClosure
+ single: rinterface; SexpClosure
pair: rinterface; function
:class:`SexpClosure`
Modified: branches/rpy_nextgen/doc/source/robjects.rst
===================================================================
--- branches/rpy_nextgen/doc/source/robjects.rst 2008-06-08 08:22:28 UTC
(rev 554)
+++ branches/rpy_nextgen/doc/source/robjects.rst 2008-06-08 13:28:27 UTC
(rev 555)
@@ -26,24 +26,14 @@
Python-R interface by modifying it (:mod:`rpy2.rpy_classic` is an other
example of a Python interface built on the top of :mod:`rpy2.rinterface`).
-Classes:
+Visible differences with RPy-1.x are:
-:class:`RObject`
- Parent class for R objects.
+- no CONVERSION mode in :mod:`rpy2`, the design has made this unnecessary
-:class:`RVector`
- An R vector
-:class:`REnvironment`
- An R environment.
+`r`: the instance of `R`
+==============================
-:class:`RFunction`
- An R function.
-
-
-Class R
-=======
-
This class is currently a singleton, with
its one representation instanciated when the
module is loaded:
@@ -121,15 +111,17 @@
are performed element-wise, recycling the shortest vector if
necessary.
-+-------+---------+
-| ``+`` | Add |
-+-------+---------+
-| ``-`` | Subtract|
-+-------+---------+
-| ``*`` | Multiply|
-+-------+---------+
-| ``/`` | Divide |
-+-------+---------+
++--------+---------+
+| ``+`` | Add |
++--------+---------+
+| ``-`` | Subtract|
++--------+---------+
+| ``*`` | Multiply|
++--------+---------+
+| ``/`` | Divide |
++--------+---------+
+| ``**`` | Power |
++--------+---------+
.. index::
pair: RVector;indexing
@@ -163,15 +155,22 @@
at the low-level.
+.. index::
+ pair: RVector; numpy
+
Numpy
-----
-Vectors are understood as Numpy or Numeric arrays::
+Vectors can be converted to :mod:`numpy` arrays using
+:meth:`array` or :meth:`asarray`::
import numpy
ltr = robjects.r.letters
ltr_np = numpy.array(ltr)
+Refer to the documentation for :class:`rinterface.SexpVector`
+for further details.
+
.. index::
pair: robjects;REnvironment
pair: robjects;globalEnv
@@ -290,22 +289,23 @@
summary(lm.D90 <- lm(weight ~ group - 1))# omitting intercept
-The :mod:`rpy2.robjects` code is
+One way to achieve the same with :mod:`rpy2.robjects` is
.. code-block:: python
- ctl = [4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14]
- trt = [4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69]
+ ctl = array.array('f', [4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14])
+ trt = array.array('f', [4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69])
group = r.gl(2, 10, 20, labels = ["Ctl","Trt"])
weight = ctl + trt
robjects.globalEnv["weight"] = weight
robjects.globalEnv["group"] = group
lm_D9 = r.lm("weight ~ group")
- r.anova(lm_D9)
+ print(r.anova(lm_D9))
- lm.D90 = r.lm("weight ~ group - 1"))
- summary(lm.D90)
+ lm_D90 = r.lm("weight ~ group - 1")
+ r.summary(lm_D90)
+
Principal component analysis
Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-06-08 08:22:28 UTC
(rev 554)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-06-08 13:28:27 UTC
(rev 555)
@@ -54,9 +54,12 @@
#include "Python.h"
+
#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>
+
+#define R_INTERFACE_PTRS
#include <Rinterface.h>
#include <R_ext/Complex.h>
#include <Rembedded.h>
@@ -192,7 +195,10 @@
//return NULL;
}
- printf("--->\n");
+ if (writeConsoleCallback == NULL) {
+ return;
+ }
+
result = PyEval_CallObject(writeConsoleCallback, arglist);
Py_DECREF(arglist);
@@ -240,13 +246,12 @@
embeddedR_isInitialized = Py_True;
Py_INCREF(Py_True);
-#ifdef R_INTERFACE_PTRS
+ #ifdef R_INTERFACE_PTRS
/* Redirect R console output */
- extern void (*ptr_R_WriteConsole)(char *, int);
ptr_R_WriteConsole = EmbeddedR_WriteConsole;
R_Outputfile = NULL;
R_Consolefile = NULL;
-#endif
+ #endif
RPY_SEXP(globalEnv) = R_GlobalEnv;
RPY_SEXP(baseNameSpaceEnv) = R_BaseNamespace;
@@ -560,7 +565,7 @@
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
- 0,//Sexp_str, /*tp_str*/
+ 0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
@@ -580,7 +585,7 @@
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
- (initproc)Sexp_init, /*tp_init*/
+ (initproc)Sexp_init, /*tp_init*/
0, /*tp_alloc*/
Sexp_new, /*tp_new*/
0, /*tp_free*/
Modified: branches/rpy_nextgen/rpy/rinterface/tests/test_EmbeddedR.py
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/tests/test_EmbeddedR.py 2008-06-08
08:22:28 UTC (rev 554)
+++ branches/rpy_nextgen/rpy/rinterface/tests/test_EmbeddedR.py 2008-06-08
13:28:27 UTC (rev 555)
@@ -10,15 +10,14 @@
class EmbeddedRTestCase(unittest.TestCase):
def testSetWriteConsole(self):
- buf = ""
+ buf = []
def f(x):
- global buf
- buf = buf + x
+ buf.append(x)
rinterface.setWriteConsole(f)
code = rinterface.SexpVector(["3", ], rinterface.STRSXP)
rinterface.baseNameSpaceEnv["print"](code)
- self.assertEquals('[1] "3"', buf)
+ self.assertEquals('[1] "3"\n', str.join('', buf))
def suite():
suite = unittest.TestLoader().loadTestsFromTestCase(EmbeddedRTestCase)
Modified: branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py 2008-06-08
08:22:28 UTC (rev 554)
+++ branches/rpy_nextgen/rpy/robjects/tests/testREnvironment.py 2008-06-08
13:28:27 UTC (rev 555)
@@ -7,6 +7,8 @@
def testNew(self):
env = robjects.REnvironment()
self.assertEquals(rinterface.ENVSXP, env.typeof())
+
+ def testNewValueError(self):
self.assertRaises(ValueError, robjects.REnvironment, 'a')
def testSetItem(self):
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRObject.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRObject.py 2008-06-08
08:22:28 UTC (rev 554)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRObject.py 2008-06-08
13:28:27 UTC (rev 555)
@@ -15,8 +15,7 @@
self.assertTrue(identical(ro_v, ri_v)[0])
- #FIXME: why isn't this working ?
- #del(ri_v)
+ del(ri_v)
self.assertEquals(rinterface.INTSXP, ro_v.typeof())
def testRepr(self):
Modified: branches/rpy_nextgen/rpy/robjects/tests/testRVector.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/testRVector.py 2008-06-08
08:22:28 UTC (rev 554)
+++ branches/rpy_nextgen/rpy/robjects/tests/testRVector.py 2008-06-08
13:28:27 UTC (rev 555)
@@ -43,12 +43,14 @@
for i, si in enumerate(myIndex):
self.assertEquals(mySeq[si-1], mySubset[i])
+ def testSubsetRecyclingRule(self):
# recycling rule
v = robjects.RVector(array.array('i', range(1, 23)))
m = robjects.r.matrix(v, ncol = 2)
col = m.subset(True, 1)
self.assertEquals(11, len(col))
+ def testSubsetLiet(self):
# list
letters = robjects.baseNameSpaceEnv["letters"]
myList = rlist(l=letters, f="foo")
@@ -60,8 +62,12 @@
letters = robjects.baseNameSpaceEnv["letters"]
self.assertEquals('a', letters[0])
self.assertEquals('z', letters[25])
+
+ def testGetItemOutOfBounds(self):
+ letters = robjects.baseNameSpaceEnv["letters"]
self.assertRaises(IndexError, letters.__getitem__, 26)
-
+
+ def getItemList(self):
mylist = rlist(letters, "foo")
idem = robjects.baseNameSpaceEnv["identical"]
self.assertTrue(idem(letters, mylist[0]))
Modified: branches/rpy_nextgen/rpy/rpy_classic.py
===================================================================
--- branches/rpy_nextgen/rpy/rpy_classic.py 2008-06-08 08:22:28 UTC (rev
554)
+++ branches/rpy_nextgen/rpy/rpy_classic.py 2008-06-08 13:28:27 UTC (rev
555)
@@ -111,6 +111,25 @@
class_table = Dict_With_Mode({})
+def seq2vec(seq):
+ types = [bool, int, float, str]
+ has_type = [False, False, False, False]
+ for tp_i, tp in enumerate(types):
+ for elt in seq:
+ if isinstance(elt, tp):
+ has_type[tp_i] = True
+ r_type = None
+ if has_type[3]:
+ r_type = ri.STRSXP
+ elif has_type[2]:
+ r_type = ri.REALSXP
+ elif has_type[1]:
+ r_type = ri.INTSXP
+ elif has_type[0]:
+ r_type = ri.LGLSXP
+ if r_type is not None:
+ vec = ri.SexpVector(seq, r_type)
+ return vec
def py2rpy(obj):
if isinstance(obj, int):
@@ -125,25 +144,9 @@
if isinstance(obj, complex):
robj = ri.SexpVector([obj, ], ri.CPLSXP)
return robj
- if isinstance(obj, list):
- types = [bool, int, float, str]
- has_type = [False, False, False, False]
- for tp_i, tp in enumerate(types):
- for elt in obj:
- if isinstance(elt, tp):
- has_type[tp_i] = True
- r_type = None
- if has_type[3]:
- r_type = ri.STRSXP
- elif has_type[2]:
- r_type = ri.REALSXP
- elif has_type[1]:
- r_type = ri.INTSXP
- elif has_type[0]:
- r_type = ri.LGLSXP
- if r_type is not None:
- robj = ri.SexpVector(obj, r_type)
- return robj
+ if isinstance(obj, list) or isinstance(obj, tuple):
+ robj = seq2vec(obj)
+ return robj
raise ValueError("Don't know what to do with 'obj'.")
def rpy2py_basic(obj):
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
rpy-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list