Revision: 564
http://rpy.svn.sourceforge.net/rpy/?rev=564&view=rev
Author: lgautier
Date: 2008-06-25 13:50:25 -0700 (Wed, 25 Jun 2008)
Log Message:
-----------
Long-due commit.
setup:
o package name is now ryp2 (no longer rpython)
o version bumped to 1.0a1 (might change to 2.0a1, as version number
can be confusing - rpy has 1.0.x)
doc:
o fixes and additions
rinterface:
o cut dead code
o default environment for do_eval_expr is now R_GlobalEnv
o restore evaluation of R functions in their CLOENV
robjects:
o class Formula
o aliases for (Str|Int|Float)SexpVector classes in rinterface
Modified Paths:
--------------
branches/rpy_nextgen/demos/radmin.py
branches/rpy_nextgen/doc/source/conf.py
branches/rpy_nextgen/doc/source/overview.rst
branches/rpy_nextgen/doc/source/rinterface.rst
branches/rpy_nextgen/doc/source/robjects.rst
branches/rpy_nextgen/rpy/rinterface/__init__.py
branches/rpy_nextgen/rpy/rinterface/rinterface.c
branches/rpy_nextgen/rpy/robjects/__init__.py
branches/rpy_nextgen/rpy/robjects/tests/__init__.py
branches/rpy_nextgen/setup.py
Modified: branches/rpy_nextgen/demos/radmin.py
===================================================================
--- branches/rpy_nextgen/demos/radmin.py 2008-06-15 22:10:56 UTC (rev
563)
+++ branches/rpy_nextgen/demos/radmin.py 2008-06-25 20:50:25 UTC (rev
564)
@@ -1,5 +1,6 @@
"""
-A front-end to R's packags, and help/documentation systems
+An R frontend
+
"""
import os, sys
Modified: branches/rpy_nextgen/doc/source/conf.py
===================================================================
--- branches/rpy_nextgen/doc/source/conf.py 2008-06-15 22:10:56 UTC (rev
563)
+++ branches/rpy_nextgen/doc/source/conf.py 2008-06-25 20:50:25 UTC (rev
564)
@@ -44,7 +44,7 @@
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
-release = '1.0a0'
+release = '1.0a1'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
Modified: branches/rpy_nextgen/doc/source/overview.rst
===================================================================
--- branches/rpy_nextgen/doc/source/overview.rst 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/doc/source/overview.rst 2008-06-25 20:50:25 UTC
(rev 564)
@@ -54,7 +54,7 @@
^^^^^^^^^^^^^^^^^^^^^^
Low-level interface to R, when speed and flexibility
-matter most. Here the programmer gets close(r) to R's C
+matter most. Here the programmer gets close(r) to R's C-level
API.
@@ -71,8 +71,11 @@
and :mod:`rpy2.robjects`: an :class:`rpy2.rinterface.SexpClosure`
can be given any :class:`rpy2.robjects.RObject` as a parameter while
any :class:`rpy2.robjects.RFunction` can be given any
-:class:`rpy2.rinterface.Sexp`.
+:class:`rpy2.rinterface.Sexp`. Choosing inheritance does not only
+come with advantages: `setters` on `R` objects would be more intuitive
+with a container/delegation approach.
The module :mod:`rpy2.rpy_classic` is using delegation, letting us
demonstrate how to extend :mod:`rpy2.rinterface` with an alternative
-to inheritance.
\ No newline at end of file
+to inheritance.
+
Modified: branches/rpy_nextgen/doc/source/rinterface.rst
===================================================================
--- branches/rpy_nextgen/doc/source/rinterface.rst 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/doc/source/rinterface.rst 2008-06-25 20:50:25 UTC
(rev 564)
@@ -46,8 +46,8 @@
.. note::
If calling :func:`initEmbeddedR` returns an error stating that
- `R_HOME` is defined, you should either have the R executable in
- your path ($PATH on unix-alikes, %Path% on Microsoft Windows) or
+ `R_HOME` is not defined, you should either have the R executable in
+ your path (`$PATH` on unix-alikes, `%Path%` on Microsoft Windows) or
have the environment variable `R_HOME` defined.
R space and Python space
@@ -86,8 +86,8 @@
The base package has a namespace, that can be accessed as an environment.
.. note::
- Depending on what is in globalEnv and on the attached packages, base
- objects can be masked when starting the search from globalEnv. Use this
+ Depending on what is in `globalEnv` and on the attached packages, base
+ objects can be masked when starting the search from `globalEnv`. Use this
environment when you want to be sure to access a function you know to be
in the base namespace.
Modified: branches/rpy_nextgen/doc/source/robjects.rst
===================================================================
--- branches/rpy_nextgen/doc/source/robjects.rst 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/doc/source/robjects.rst 2008-06-25 20:50:25 UTC
(rev 564)
@@ -1,4 +1,4 @@
-.. index::
+. index::
module: rpy2.robjects
@@ -274,14 +274,65 @@
The class inherits from the class
:class:`rpy2.rinterface.SexpClosure`.
+.. index::
+ pair: robjects; RFormula
+ single: formula
+Formulae
+========
+
+For tasks such as modelling and plotting, an R formula can be
+a terse, yet readable, way of expressing what is wanted.
+
+In R, it generally looks like:
+
+.. code-block:: r
+
+ x <- 1:10
+ y <- x + rnorm(10, sd=0.2)
+
+ fit <- lm(y ~ x)
+
+In the call to `lm`, the argument is a `formula`.
+A formula is a `R` language object, and the terms in the formula
+are evaluated in the environment it was defined in. Without further
+specification, that environment is the environment in which the
+the formula is created.
+
+The class :class:`robjects.RFormula` is representing an `R` formula,
+and represents a convenient way of specifying your code.
+
+.. code-block:: python
+
+ x = robjects.RVector(array.array('i', range(1, 11)))
+ y = x + robjects.r.rnorm(10, sd=0.2)
+
+ fmla = robjects.RFormula('y ~ x')
+ env = fmla.getenvironment()
+ env['x'] = x
+ env['y'] = y
+
+ fit = robjects.r.lm(fmla)
+
+One drawback with that approach is that pretty printing of
+the `fit` object is note quite as clear as what one would
+expect when working in `R`.
+However, by evaluating R code on
+the fly, we can obtain a `fit` object that will display
+nicely:
+
+.. code-block:: python
+
+ fit = robjects.r('lm(%s)' %fmla.__repr__())
+
+
Mapping between rpy2 objects and other python objects
=====================================================
-The mapping between low-level objects is performed by the
-functions XXX and XXX.
+The mapping between low-level objects is performed on
+the fly by functions XXX
-A developper can easily add his own mapping XXX.
+Those functions can be modifyied to satisfy all requirements.
Examples
Modified: branches/rpy_nextgen/rpy/rinterface/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/__init__.py 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/rpy/rinterface/__init__.py 2008-06-25 20:50:25 UTC
(rev 564)
@@ -35,3 +35,19 @@
from rpy2.rinterface.rinterface import *
+
+
+class StrSexpVector(SexpVector):
+ def __init__(self, v):
+ super(StrSexpVector, self).__init__(v, STRSXP)
+
+
+class IntSexpVector(SexpVector):
+ def __init__(self, v):
+ super(StrSexpVector, self).__init__(v, INTSXP)
+
+
+class FloatSexpVector(SexpVector):
+ def __init__(self, v):
+ super(StrSexpVector, self).__init__(v, REALSXP)
+
Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-06-25 20:50:25 UTC
(rev 564)
@@ -592,24 +592,8 @@
};
-/* static PyObject* */
-/* Sexp_new(PyTypeObject *type, PyObject *args) */
-/* { */
-/* PyObject object, res; */
-/* if (!PyArg_ParseTuple(args, "O:new", */
-/* &object)) */
-/* PyErr_Format(PyExc_ValueError, "Can only instanciate from
PySexpObject"); */
-/* return NULL; */
-/* res = (PySexpObject *)_PyObject_New(&Sexp_Type); */
-/* if (!res) */
-/* PyErr_NoMemory(); */
-/* res->sexp = sexp; */
-/* return res; */
-/* } */
-
-
/*
* Closure-type Sexp.
*/
@@ -624,8 +608,11 @@
//FIXME: if env_R is null, use R_BaseEnv
+ //shouldn't it be R_GlobalContext (but then it throws a NULL error) ?
if (isNull(env_R)) {
- env_R = R_BaseEnv;
+ //env_R = R_BaseEnv;
+ env_R = R_GlobalEnv;
+ //env_R = R_GlobalContext;
}
/* Enable our handler for SIGINT inside the R
@@ -771,8 +758,8 @@
}
//FIXME: R_GlobalContext ?
- PROTECT(res_R = do_eval_expr(call_R, R_GlobalEnv));
- //PROTECT(res_R = do_eval_expr(call_R, CLOENV(fun_R)));
+ //PROTECT(res_R = do_eval_expr(call_R, R_GlobalEnv));
+ PROTECT(res_R = do_eval_expr(call_R, CLOENV(fun_R)));
/* if (!res) { */
/* UNPROTECT(2); */
Modified: branches/rpy_nextgen/rpy/robjects/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/__init__.py 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/rpy/robjects/__init__.py 2008-06-25 20:50:25 UTC
(rev 564)
@@ -10,7 +10,11 @@
import array
import rpy2.rinterface as rinterface
+StrSexpVector = rinterface.StrSexpVector
+IntSexpVector = rinterface.IntSexpVector
+FloatSexpVector = rinterface.FloatSexpVector
+
#FIXME: close everything when leaving (check RPy for that).
def default_ri2py(o):
@@ -28,6 +32,8 @@
res = REnvironment(o)
elif isinstance(o, rinterface.SexpS4):
res = RS4(o)
+ elif rinterface.baseNameSpaceEnv['class'](o)[0] == 'formula':
+ res = RFormula(o)
else:
res = RObject(o)
return res
@@ -290,13 +296,34 @@
res = ri2py(res)
return res
+
class RS4(RObjectMixin, rinterface.SexpS4):
def __getattr__(self, attr):
res = self.do_slot(attr)
return res
+
+class RFormula(RObjectMixin, rinterface.Sexp):
+
+ def __init__(self, formula, environment = rinterface.globalEnv):
+ inpackage = rinterface.baseNameSpaceEnv["::"]
+ asformula = inpackage(StrSexpVector(['stats', ]),
+ StrSexpVector(['as.formula', ]))
+ robj = asformula(rinterface.SexpVector(StrSexpVector([formula, ])),
+ env = environment)
+ super(RFormula, self).__init__(robj)
+
+ def getenvironment(self):
+ """ Return the R environment in which the formula will look for
+ its variables. """
+ res = self.do_slot(".Environment")
+ res = ri2py(res)
+ return res
+
+
+
class R(object):
_instance = None
Modified: branches/rpy_nextgen/rpy/robjects/tests/__init__.py
===================================================================
--- branches/rpy_nextgen/rpy/robjects/tests/__init__.py 2008-06-15 22:10:56 UTC
(rev 563)
+++ branches/rpy_nextgen/rpy/robjects/tests/__init__.py 2008-06-25 20:50:25 UTC
(rev 564)
@@ -3,6 +3,7 @@
import testRObject
import testRVector
import testRArray
+import testRFormula
import testRFunction
import testREnvironment
import testRobjects
@@ -13,12 +14,14 @@
suite_RArray = testRArray.suite()
suite_RFunction = testRFunction.suite()
suite_REnvironment = testREnvironment.suite()
+ suite_RFormula = testRFormula.suite()
suite_Robjects = testRobjects.suite()
alltests = unittest.TestSuite([suite_RObject,
suite_RVector,
suite_RArray,
suite_RFunction,
suite_REnvironment,
+ suite_RFormula,
suite_Robjects ])
return alltests
Modified: branches/rpy_nextgen/setup.py
===================================================================
--- branches/rpy_nextgen/setup.py 2008-06-15 22:10:56 UTC (rev 563)
+++ branches/rpy_nextgen/setup.py 2008-06-25 20:50:25 UTC (rev 564)
@@ -2,17 +2,9 @@
import os, os.path, sys, shutil, re, itertools
from distutils.core import setup, Extension
-#FIXME: still needed ?
-try:
- import ctypes
-except Exception, e:
- print(e)
- print("A working 'ctypes' module is required.")
- sys.exit(1)
-
pack_name = 'rpy2'
-pack_version = '1.0-a0'
+pack_version = '1.0-a1'
RHOMES = os.getenv('RHOMES')
@@ -133,7 +125,7 @@
pack_dir = {pack_name: 'rpy'}
-setup(name = "rpython",
+setup(name = pack_name,
version = pack_version,
description = "Python interface to the R language",
url = "http://rpy.sourceforge.net",
@@ -141,6 +133,8 @@
ext_modules = rinterface_exts,
package_dir = pack_dir,
packages = [pack_name,
+ pack_name+'.rlike',
+ pack_name+'.rlike.tests',
pack_name+'.robjects',
pack_name+'.robjects.tests'] + \
[pack_name + '.rinterface', pack_name + '.rinterface.tests']
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