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 rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list