Revision: 641
          http://rpy.svn.sourceforge.net/rpy/?rev=641&view=rev
Author:   lgautier
Date:     2008-08-25 07:08:15 +0000 (Mon, 25 Aug 2008)

Log Message:
-----------
rinterface:
  - fixed signature for Sexp_get getter
  - added emptyEnv
  - new method Sexp_do_slot_assign

rlike:
  - added paramater 'cmp' to order()

robjects:
  - fixed DataFrame methods rownames() and colnames()

doc:
  - more editing of the documentation

Modified Paths:
--------------
    branches/rpy_nextgen/NEWS
    branches/rpy_nextgen/doc/source/overview.rst
    branches/rpy_nextgen/doc/source/rinterface.rst
    branches/rpy_nextgen/doc/source/rlike.rst
    branches/rpy_nextgen/doc/source/robjects.rst
    branches/rpy_nextgen/rpy/rinterface/rinterface.c
    branches/rpy_nextgen/rpy/rinterface/tests/test_Sexp.py
    branches/rpy_nextgen/rpy/rlike/indexing.py
    branches/rpy_nextgen/rpy/robjects/__init__.py

Modified: branches/rpy_nextgen/NEWS
===================================================================
--- branches/rpy_nextgen/NEWS   2008-08-24 13:47:05 UTC (rev 640)
+++ branches/rpy_nextgen/NEWS   2008-08-25 07:08:15 UTC (rev 641)
@@ -14,6 +14,10 @@
 
 - method :meth:`rsame` to test if the underlying R objects for two 
:class:`Sexp` are the same.
 
+- added `emptyEnv` (R's C-level `R_EmptyEnv`)
+
+- added method :meth:`Sexp.do_slot_assign`
+
 :mod:`rpy2.robjects`:
 
 - R string vectors can now be built from Python unicode objects
@@ -42,6 +46,7 @@
 
 - R objects of type EXPRSXP are now handled as vectors (... but this may 
change again)
 
+
 :mod:`rpy2.robjects`:
 
 - :class:`R` remains a singleton, but does not throw an exception when 
multiple instances are requested
@@ -64,6 +69,7 @@
 
 - complex vectors should now be handled properly by 
:mod:`rpy2.rinterface.robjects`.
 
+- methods :meth:`rownames` and :meth:`colnames` for :class:`RDataFrame` were 
incorrect.
 
 Release 2.0.0a2
 ===============

Modified: branches/rpy_nextgen/doc/source/overview.rst
===================================================================
--- branches/rpy_nextgen/doc/source/overview.rst        2008-08-24 13:47:05 UTC 
(rev 640)
+++ branches/rpy_nextgen/doc/source/overview.rst        2008-08-25 07:08:15 UTC 
(rev 641)
@@ -139,10 +139,11 @@
 
 - the use of the module simple from both a Python or R user's perspective
 
-- minimize the need for knowledge about R, and the need for tricks are 
workaround.
-- the possibility to customize a lot only with Python (without having to go to 
C-level).
+- minimize the need for knowledge about R, and the need for tricks and 
workarounds.
 
+- the possibility to customize a lot while remaining at the Python level 
(without having to go down to C-level).
 
+
 :mod:`rpy2.robjects` implements an extension to the interface in
 :mod:`rpy2.rinterface` by extending the classes for R
 objects defined there with child classes.

Modified: branches/rpy_nextgen/doc/source/rinterface.rst
===================================================================
--- branches/rpy_nextgen/doc/source/rinterface.rst      2008-08-24 13:47:05 UTC 
(rev 640)
+++ branches/rpy_nextgen/doc/source/rinterface.rst      2008-08-25 07:08:15 UTC 
(rev 641)
@@ -222,7 +222,7 @@
       called :meth:`do_slot` in the C interface to R. 
 
       :param name: string
-      :rtype: Sexp (or Sexp-inheriting) object
+      :rtype: instance of :class:`Sexp`
 
       >>> matrix = rinterface.globalEnv.get("matrix")
       >>> letters = rinterface.globalEnv.get("letters")
@@ -232,6 +232,14 @@
       [13, 2]
       >>>
 
+   .. method:: do_slot_assign(name, value)
+
+      Assign value to the slot with the given name
+
+      :param name: string
+      :param value: instance of :class:`Sexp`
+
+
    .. method:: rsame(sexp_obj)
 
       Tell whether the underlying R object for sexp_obj is the same or not.
@@ -523,10 +531,9 @@
    def rsearch():
        """ Return a list of package environments corresponding to the
        R search path. """
-       emptyenv = ri.baseNameSpaceEnv.get('emptyenv')()
        spath = [ri.globalEnv, ]
        item = ri.globalEnv.enclos()
-       while not item.rsame(emptyenv):
+       while not item.rsame(ri.emptyEnv):
            spath.append(item)
           item = item.enclos()
        spath.append(ri.baseNameSpaceEnv)
@@ -541,7 +548,6 @@
 
    def wherefrom(name, startenv=ri.globalEnv):
        """ when calling 'get', where the R object is coming from. """
-       emptyenv = ri.baseNameSpaceEnv.get('emptyenv')()
        env = startenv
        obj = None
        retry = True
@@ -551,7 +557,7 @@
                retry = False
            except LookupError, knf:
                env = env.enclos()
-              if env.rsame(emptyenv):
+              if env.rsame(ri.emptyEnv):
                    retry = False
                else:
                    retry = True
@@ -723,6 +729,9 @@
 :const:`LANGSXP`
   Language object.
 
+:const:`EXPRSXP`
+  Unevaluated expression.
+
 Other types
 ^^^^^^^^^^^
 
@@ -736,7 +745,7 @@
   Instance of class S4. Represented by :class:`rpy2.rinterface.SexpS4`.
 
 
-Types you should not meet
+Types one should not meet
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 :const:`PROMSXP`

Modified: branches/rpy_nextgen/doc/source/rlike.rst
===================================================================
--- branches/rpy_nextgen/doc/source/rlike.rst   2008-08-24 13:47:05 UTC (rev 
640)
+++ branches/rpy_nextgen/doc/source/rlike.rst   2008-08-25 07:08:15 UTC (rev 
641)
@@ -96,21 +96,52 @@
 .. autoclass:: rpy2.rlike.container.TaggedList
    :members:
 
+
+.. module:: rpy2.rlike.functional
+
 Tools for working with sequences
 ================================
 
-.. autofunction:: rpy2.rlike.functional.tapply
+.. autofunction:: tapply
 
 >>> import rpy2.rlike.functional as rlf
 >>> rlf.tapply((1,2,3), ('a', 'b', 'a'), sum)
 [('a', 4), ('b', 2)]
 
 
+.. module:: rpy2.rlike.indexing
+
 Indexing
 ========
 
-.. function:: rpy2.rlike.indexing.order
+Much of the R-style indexing can be achieved with Python's list comprehension:
 
+>>> x = ('a', 'b', 'c')
+>>> x_i = (0, 2)
+>>> [x[i] for i in x_i]
+['a', 'c']
+
+In `R`, negative indexes mean that values should be excluded. Again,
+list comprehension can be used:
+
+>>> x = ('a', 'b', 'c') 
+>>> x_i = (0, 2)
+
+.. function:: order(seq, cmp = default_cmp, reverse = False)
+
+   Give the order in which to take the items in the sequence `seq` and
+   have them sorted.
+   The optional function cmp should return +1, -1, or 0.
+
+   :param seq: sequence
+   :param cmp: function
+   :param reverse: boolean
+   :rtype: list of integers
+
 >>> import rpy2.rlike.indexing as rli
->>> rli.order(('a', 'c', 'b'))
+>>> x = ('a', 'c', 'b')
+>>> o = rli.order(x)
+>>> o
 [0, 2, 1]
+>>> [x[i] for i in o]
+['a', 'b', 'c']
\ No newline at end of file

Modified: branches/rpy_nextgen/doc/source/robjects.rst
===================================================================
--- branches/rpy_nextgen/doc/source/robjects.rst        2008-08-24 13:47:05 UTC 
(rev 640)
+++ branches/rpy_nextgen/doc/source/robjects.rst        2008-08-25 07:08:15 UTC 
(rev 641)
@@ -257,6 +257,7 @@
    :show-inheritance:
    :members:
 
+
 Environments
 ============
 
@@ -304,7 +305,11 @@
 
 >>> env = robjects.r.baseenv()
 >>> len([x for x in env])
+<a long list returned>
 
+For further information, read the documentation for the
+class :class:`rpy2.rinterface.SexpEnvironment`.
+
 .. index::
    pair: robjects; RFunction
    pair: robjects; function

Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.c    2008-08-24 13:47:05 UTC 
(rev 640)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.c    2008-08-25 07:08:15 UTC 
(rev 641)
@@ -138,6 +138,7 @@
 
 static PySexpObject *globalEnv;
 static PySexpObject *baseNameSpaceEnv;
+static PySexpObject *emptyEnv;
 static PySexpObject *na_string;
 
 /* early definition of functions */
@@ -363,6 +364,7 @@
 
   RPY_SEXP(globalEnv) = R_GlobalEnv;
   RPY_SEXP(baseNameSpaceEnv) = R_BaseNamespace;
+  RPY_SEXP(emptyEnv) = R_EmptyEnv;
   RPY_SEXP(na_string) = NA_STRING;
 
   GetErrMessage_SEXP = findVar(install("geterrmessage"), 
@@ -406,6 +408,7 @@
 
   RPY_SEXP(globalEnv) = R_EmptyEnv;
   RPY_SEXP(baseNameSpaceEnv) = R_EmptyEnv;
+  RPY_SEXP(emptyEnv) = R_EmptyEnv;
   GetErrMessage_SEXP = R_NilValue; 
 
   //FIXME: Is it possible to reinitialize R later ?
@@ -547,6 +550,50 @@
             ":rtype: instance of type or subtype 
:class:`rpy2.rinterface.Sexp`");
 
 static PyObject*
+Sexp_do_slot_assign(PyObject *self, PyObject *args)
+{
+
+  SEXP sexp = RPY_SEXP(((PySexpObject*)self));
+  if (! sexp) {
+    PyErr_Format(PyExc_ValueError, "NULL SEXP.");
+    return NULL;;
+  }
+
+  char *name_str;
+  PyObject *value;
+  if (! PyArg_ParseTuple(args, "sO", 
+                        &name_str,
+                        &value)) {
+    return NULL;
+  }
+
+  if (! PyObject_IsInstance(value, 
+                         (PyObject*)&Sexp_Type)) {
+      PyErr_Format(PyExc_ValueError, "Value must be an instance of Sexp.");
+      return NULL;
+  }
+
+  if (! R_has_slot(sexp, install(name_str))) {
+    PyErr_SetString(PyExc_LookupError, "The object has no such attribute.");
+    return NULL;
+  }
+  SEXP value_sexp = RPY_SEXP((PySexpObject *)value);
+  if (! value_sexp) {
+    PyErr_Format(PyExc_ValueError, "NULL SEXP.");
+    return NULL;;
+  }
+
+  SET_SLOT(sexp, install(name_str), value_sexp);
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+PyDoc_STRVAR(Sexp_do_slot_assign_doc,
+            "Set the attribute/slot for an R object.\n"
+            "\n"
+            ":param name: string\n"
+            ":param value: instance of rpy2.rinterface.Sexp");
+
+static PyObject*
 Sexp_named_get(PyObject *self)
 {
   SEXP sexp = RPY_SEXP(((PySexpObject*)self));
@@ -563,7 +610,7 @@
 See the R-extensions manual for further details.");
 
 static PyObject*
-Sexp_sexp_get(PyObject *self)
+Sexp_sexp_get(PyObject *self, void *closure)
 {
   SEXP sexp = RPY_SEXP(((PySexpObject*)self));
 
@@ -575,6 +622,23 @@
   PyObject *res = PyCObject_FromVoidPtr(sexp, NULL);
   return res;
 }
+
+/* static PyObject* */
+/* Sexp_sexp_set(PyObject *self, PyObject *obj, void *closure) */
+/* { */
+/*   if (! PyCObject_Check(obj)) { */
+/*     PyErr_SetString(PyExc_TypeError, "The value must be a CObject."); */
+/*     return -1; */
+/*   } */
+/*   SEXP sexp = (SEXP) PyCObject_AsVoidPtr(PyObject* obj); */
+/*   if (! sexp) { */
+/*     PyErr_Format(PyExc_ValueError, "NULL SEXP."); */
+/*     return -1; */
+/*   } */
+/*   RPY_SEXP(((PySexpObject*)self)) = sexp; */
+
+/*   return 0; */
+/* } */
 PyDoc_STRVAR(Sexp_sexp_doc,
             "Opaque C pointer to the underlying R object");
 
@@ -611,6 +675,8 @@
 static PyMethodDef Sexp_methods[] = {
   {"do_slot", (PyCFunction)Sexp_do_slot, METH_O,
   Sexp_do_slot_doc},
+  {"do_slot_assign", (PyCFunction)Sexp_do_slot_assign, METH_VARARGS,
+   Sexp_do_slot_assign_doc},
   {"rsame", (PyCFunction)Sexp_rsame, METH_O,
   Sexp_rsame_doc},
   {NULL, NULL}          /* sentinel */
@@ -2501,6 +2567,12 @@
 /*   //FIXME: DECREF ? */
 /*   Py_DECREF(baseNameSpaceEnv); */
 
+  emptyEnv = (PySexpObject*)Sexp_new(&EnvironmentSexp_Type,
+                                    Py_None, Py_None);
+  RPY_SEXP(emptyEnv) = R_EmptyEnv;
+  if (PyDict_SetItemString(d, "emptyEnv", 
+                          (PyObject *)emptyEnv) < 0)
+    return;
 
   /* Add SXP types */
   validSexpType = calloc(maxValidSexpType, sizeof(char *));

Modified: branches/rpy_nextgen/rpy/rinterface/tests/test_Sexp.py
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/tests/test_Sexp.py      2008-08-24 
13:47:05 UTC (rev 640)
+++ branches/rpy_nextgen/rpy/rinterface/tests/test_Sexp.py      2008-08-25 
07:08:15 UTC (rev 641)
@@ -50,8 +50,17 @@
         for i, n in enumerate(iris_names):
             self.assertEquals(iris_names[i], names[i])
 
-        self.assertRaises(LookupError, sexp.do_slot, "foo")       
+        self.assertRaises(LookupError, sexp.do_slot, "foo")  
 
+    def testDo_slot_assign(self):
+        data_func = rinterface.globalEnv.get("data")
+        data_func(rinterface.SexpVector(["iris", ], rinterface.STRSXP))
+        sexp = rinterface.globalEnv.get("iris")
+        iris_names = rinterface.StrSexpVector(['a', 'b', 'c', 'd', 'e'])
+        sexp.do_slot_assign("names", iris_names)
+        names = [x for x in sexp.do_slot("names")]
+        self.assertEquals(['a', 'b', 'c', 'd', 'e'], names)
+
     def testSexp_rsame_true(self):
         sexp_a = rinterface.globalEnv.get("letters")
         sexp_b = rinterface.globalEnv.get("letters")

Modified: branches/rpy_nextgen/rpy/rlike/indexing.py
===================================================================
--- branches/rpy_nextgen/rpy/rlike/indexing.py  2008-08-24 13:47:05 UTC (rev 
640)
+++ branches/rpy_nextgen/rpy/rlike/indexing.py  2008-08-25 07:08:15 UTC (rev 
641)
@@ -1,17 +1,24 @@
 
-def order(sortable, reverse = False):
-    o = range(len(sortable))
-    def cmp(x, y):
-        x = sortable[x]
-        y = sortable[y]
-        if x < y: 
-            return -1
-        elif x > y:
-            return +1
-        else:
-            return 0
+def default_cmp(x, y):
+    """ Default comparison function """
+    if x < y: 
+        return -1
+    elif x > y:
+        return +1
+    else:
+        return 0
+
+def order(seq, cmp = default_cmp, reverse = False):
+    """ Return the order in which to take the items to obtained
+    a sorted sequence."""
+    o = range(len(seq))
+
+    def wrap_cmp(x, y):
+        x = seq[x]
+        y = seq[y]
+        return cmp(x, y)
         
-    o.sort(cmp = cmp, reverse = reverse)
+    o.sort(cmp = wrap_cmp, reverse = reverse)
 
     return o
 

Modified: branches/rpy_nextgen/rpy/robjects/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/__init__.py       2008-08-24 13:47:05 UTC 
(rev 640)
+++ branches/rpy_nextgen/rpy/robjects/__init__.py       2008-08-25 07:08:15 UTC 
(rev 641)
@@ -54,7 +54,6 @@
         res = RObject(o)
     return res
 
-#FIXME: better names for the functions
 ri2py = default_ri2py
 
 
@@ -350,20 +349,23 @@
     
     def rownames(self):
         """ Row names
-        :rype: SexpVector
+        
+        :rtype: SexpVector
         """
-        return baseNameSpaceEnv["colnames"](self)[0]
+        res = baseNameSpaceEnv["rownames"](self)
+        return ri2py(res)
 
     def colnames(self):
         """ Column names
-        :rype: SexpVector
+
+        :rtype: SexpVector
         """
-        return baseNameSpaceEnv["colnames"](self)[0]
+        res = baseNameSpaceEnv["colnames"](self)
+        return ri2py(res)
 
 
-
 class RFunction(RObjectMixin, rinterface.SexpClosure):
-    """ An R function (aka "closure").
+    """ An R function.
     
     """
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
rpy-list mailing list
rpy-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rpy-list

Reply via email to