sage: remove outdated patch files

This commit is contained in:
Timo Kaufmann 2018-12-23 10:08:34 +01:00
parent 6f0f06ec89
commit 360eddd3a3
2 changed files with 0 additions and 782 deletions

View File

@ -1,19 +0,0 @@
diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx
index bdde6aa60f..50459534f8 100644
--- a/src/sage/libs/gap/util.pyx
+++ b/src/sage/libs/gap/util.pyx
@@ -165,14 +165,6 @@ def gap_root():
sage: from sage.libs.gap.util import gap_root
sage: gap_root() # random output
'/home/vbraun/opt/sage-5.3.rc0/local/gap/latest'
-
- If GAP_ROOT_DIR is undefined or pointing to the wrong location,
- fall back code should be used to determine gapdir::
-
- sage: import os
- sage: os.system("GAP_ROOT_DIR=/not_a_path sage -c \"sage.libs.gap.util.gap_root()\"")
- The gap-4.5.5.spkg (or later) seems to be not installed!
- ...
"""
import os.path
if os.path.exists(GAP_ROOT_DIR):

View File

@ -1,763 +0,0 @@
diff --git a/src/sage/doctest/test.py b/src/sage/doctest/test.py
index 2f4f74cfc2..c6c1bf9194 100644
--- a/src/sage/doctest/test.py
+++ b/src/sage/doctest/test.py
@@ -500,12 +500,13 @@ Test ``atexit`` support in the doctesting framework::
....: pass
Test the ``--memlimit`` option and ``# optional - memlimit``
-(but only on Linux)::
+(but only on Linux). If this test fails, the memory needed to
+run it may have increased. Try increasing the limit. ::
sage: from platform import system
sage: ok = True
sage: if system() == "Linux":
- ....: P = subprocess.Popen(["sage", "-t", "--warn-long", "0", "--memlimit=2000", "memlimit.rst"], stdout=subprocess.PIPE, **kwds)
+ ....: P = subprocess.Popen(["sage", "-t", "--warn-long", "0", "--memlimit=2100", "memlimit.rst"], stdout=subprocess.PIPE, **kwds)
....: out, err = P.communicate()
....: ok = ("MemoryError: failed to allocate" in out)
sage: ok or out
diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py
index 51a37496c2..ba982f25f7 100644
--- a/src/sage/interfaces/expect.py
+++ b/src/sage/interfaces/expect.py
@@ -1122,10 +1122,15 @@ If this all works, you can then make calls like:
EXAMPLES:
- We test all of this using the R interface. First we put
+ We test all of this using the Singular interface. First we put
10 + 15 in the input stream::
- sage: r._sendstr('abc <- 10 +15;\n')
+ sage: singular._sendstr('def abc = 10 + 15;\n')
+
+ Then we tell singular to print 10, which is an arbitrary number
+ different from the expected result 35.
+
+ sage: singular._sendstr('10;\n')
Here an exception is raised because 25 hasn't appeared yet in the
output stream. The key thing is that this doesn't lock, but instead
@@ -1135,7 +1140,7 @@ If this all works, you can then make calls like:
sage: t = walltime()
sage: try:
- ....: r._expect_expr('25', timeout=0.5)
+ ....: singular._expect_expr('25', timeout=0.5)
....: except Exception:
....: print('Did not get expression')
Did not get expression
@@ -1145,24 +1150,24 @@ If this all works, you can then make calls like:
sage: w = walltime(t); w > 0.4 and w < 10
True
- We tell R to print abc, which equals 25.
+ We tell Singular to print abc, which equals 25.
::
- sage: r._sendstr('abc;\n')
+ sage: singular._sendstr('abc;\n')
Now 25 is in the output stream, so we can wait for it.
::
- sage: r._expect_expr('25')
+ sage: singular._expect_expr('25')
- This gives us everything before the 25.
+ This gives us everything before the 25, including the 10 we printed earlier.
::
- sage: r._expect.before.decode('ascii')
- u'...abc;\r\n[1] '
+ sage: singular._expect.before.decode('ascii')
+ u'...10\r\n> '
We test interrupting ``_expect_expr`` using the GP interface,
see :trac:`6661`. Unfortunately, this test doesn't work reliably using
@@ -1203,14 +1208,7 @@ If this all works, you can then make calls like:
- ``string`` -- a string
- EXAMPLES: We illustrate this function using the R interface::
-
- sage: r._synchronize()
- sage: r._sendstr('a <- 10;\n')
- sage: r.eval('a')
- '[1] 10'
-
- We illustrate using the singular interface::
+ EXAMPLES: We illustrate this function using the Singular interface::
sage: singular._synchronize()
sage: singular._sendstr('int i = 5;')
@@ -1260,7 +1258,7 @@ If this all works, you can then make calls like:
EXAMPLES: We observe nothing, just as it should be::
- sage: r._synchronize()
+ sage: singular._synchronize()
TESTS:
diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py
index 86f401571a..f3c6120ddc 100644
--- a/src/sage/interfaces/gp.py
+++ b/src/sage/interfaces/gp.py
@@ -254,6 +254,7 @@ class Gp(ExtraTabCompletion, Expect):
self._eval_line('default(help, "gphelp -detex");')
# logfile disabled since Expect already logs
self._eval_line('default(log,0);')
+ self._eval_line("default(nbthreads,1);")
# set random seed
self.set_seed(self._seed)
diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py
index 5c75459903..06974a2324 100644
--- a/src/sage/interfaces/r.py
+++ b/src/sage/interfaces/r.py
@@ -268,17 +268,17 @@ from __future__ import print_function, absolute_import
from six.moves import range
import six
-from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement
+from .interface import Interface, InterfaceElement, InterfaceFunction, InterfaceFunctionElement
from sage.env import DOT_SAGE
import re
-import sage.rings.integer
from sage.structure.element import parent
from sage.interfaces.tab_completion import ExtraTabCompletion
from sage.docs.instancedoc import instancedoc
+from rpy2 import robjects
+from rpy2.robjects import packages
+from rpy2.robjects.conversion import localconverter
COMMANDS_CACHE = '%s/r_commandlist.sobj'%DOT_SAGE
-PROMPT = '__SAGE__R__PROMPT__> '
-prompt_re = re.compile("^>", re.M)
#there is a mirror network, but lets take #1 for now
RRepositoryURL = "http://cran.r-project.org/"
@@ -288,12 +288,156 @@ RFilteredPackages = ['.GlobalEnv']
# but package:base should cover this. i think.
RBaseCommands = ['c', "NULL", "NA", "True", "False", "Inf", "NaN"]
-class R(ExtraTabCompletion, Expect):
+def _setup_r_to_sage_converter():
+ """
+ Set up a the converter used to convert from rpy2's
+ representation of R objects to the one sage expects.
+
+ EXAMPLES::
+
+ Test
+
+ Simple numeric values are represented as vectors in R. So `1` would actually
+ be an array of length 1. We convert all vectors of length 1 to simple values,
+ whether or not they "originally" were simple values or not:
+
+ sage: r([42]).sage()
+ 42
+
+ sage: r(42).sage()
+ 42
+
+ sage: r('c("foo")').sage()
+ 'foo'
+
+ Arrays of length greater than one are treated normally:
+
+ sage: r([42, 43]).sage()
+ [42, 43]
+
+ We also convert all numeric values to integers if that is possible without
+ loss of precision:
+
+ sage: type(r([1.0]).sage()) == int
+ True
+
+ sage: r([1.0, 42.5]).sage()
+ [1, 42.5]
+
+ Matrices are converted to sage matrices:
+
+ sage: r('matrix(c(2,4,3,1,5,7), nrow=2, ncol=3)').sage()
+ [2 3 5]
+ [4 1 7]
+
+ More complex r structures are represented by dictionaries:
+
+ sage: r.summary(1).sage()
+ {'DATA': [1, 1, 1, 1, 1, 1],
+ '_Names': ['Min.', '1st Qu.', 'Median', 'Mean', '3rd Qu.', 'Max.'],
+ '_r_class': ['summaryDefault', 'table']}
+
+ sage: r.options(width="60").sage()
+ {'DATA': {'width': 60}, '_Names': 'width'}
+
+ The conversion can handle "not a number", infintiy, imaginary values and
+ missing values:
+
+ sage: r(-17).sqrt().sage()
+ nan
+ sage: r('-17+0i').sqrt().sage()
+ 4.123105625617661j
+ sage: r('NA').sage()
+ NA
+ sage: inf = r('Inf'); inf.sage()
+ inf
+
+
+ Character Vectors are represented by regular python arrays:
+
+ sage: labs = r.paste('c("X","Y")', '1:10', sep='""'); labs.sage()
+ ['X1', 'Y2', 'X3', 'Y4', 'X5', 'Y6', 'X7', 'Y8', 'X9', 'Y10']
+ """
+ from rpy2.rinterface import SexpVector, ListSexpVector, FloatSexpVector
+ from rpy2.robjects.conversion import Converter
+
+ # convert rpy2's representation of r objects to the one sage expects (as defined by the old
+ # expect interface)
+ cv = Converter('r to sage converter')
+
+ # fallback
+ cv.ri2py.register(object, lambda obj: obj)
+
+ def float_to_int_if_possible(f):
+ # preserve the behaviour of the old r parser, e.g. return 1 instead of 1.0
+ return int(f) if isinstance(f, int) or f.is_integer() else round(f, 16) # TODO investigate the rounding
+ cv.ri2py.register(float, float_to_int_if_possible)
+
+ def list_to_singleton_if_possible(l):
+ if len(l) == 1:
+ return l[0]
+ else:
+ return l
+
+ def _vector(vec):
+ attrs = vec.list_attrs()
+ # Recursive calls have to be made explicitly
+ # https://bitbucket.org/rpy2/rpy2/issues/363/custom-converters-are-not-applied
+ data = list_to_singleton_if_possible([ cv.ri2py(val) for val in vec ])
+ rclass = list(vec.do_slot('class')) if 'class' in attrs else vec.rclass
+
+ if 'names' in attrs:
+ # seperate names and values, call ri2py recursively to convert elements
+ names = list_to_singleton_if_possible(list(vec.do_slot('names')))
+ return {
+ 'DATA': data,
+ '_Names': names,
+ '_r_class': rclass,
+ }
+ else:
+ # if no names are present, convert to a normal list or a single value
+ return data
+ cv.ri2py.register(SexpVector, _vector)
+
+ def _matrix(mat):
+ if 'dim' in mat.list_attrs():
+ try:
+ from sage.matrix.constructor import matrix
+ dimensions = mat.do_slot("dim")
+ # TODO: higher dimensions? happens often in statistics
+ if len(dimensions) != 2:
+ raise TypeError
+ (nrow, ncol) = dimensions
+ #since R does it the other way round, we assign
+ #transposed and then transpose the matrix :)
+ m = matrix(ncol, nrow, [cv.ri2py(i) for i in mat])
+ return m.transpose()
+ except TypeError:
+ pass
+ else:
+ return _vector(mat)
+ cv.ri2py.register(FloatSexpVector, _matrix)
+
+ def _list_vector(vec):
+ # we have a R list (vector of arbitrary elements)
+ attrs = vec.list_attrs()
+ names = vec.do_slot('names')
+ values = [ cv.ri2py(val) for val in vec ]
+ rclass = list(vec.do_slot('class')) if 'class' in attrs else vec.rclass
+ data = zip(names, values)
+ return {
+ 'DATA': dict(data),
+ '_Names': cv.ri2py(names),
+ # '_r_class': rclass, # FIXME why not?
+ };
+ cv.ri2py.register(ListSexpVector, _list_vector)
+
+ return cv
+
+class R(ExtraTabCompletion, Interface):
def __init__(self,
- maxread=None, script_subdirectory=None,
- server_tmpdir = None,
+ maxread=None,
logfile=None,
- server=None,
init_list_length=1024,
seed=None):
"""
@@ -319,46 +463,19 @@ class R(ExtraTabCompletion, Expect):
sage: r == loads(dumps(r))
True
"""
- Expect.__init__(self,
- # The capitalized version of this is used for printing.
- name = 'r',
+ Interface.__init__(
+ self,
+ name = 'r', # The capitalized version of this is used for printing.
+ )
- # This is regexp of the input prompt. If you can change
- # it to be very obfuscated that would be better. Even
- # better is to use sequence numbers.
- # options(prompt=\"<prompt> \")
- prompt = '> ', #default, later comes the change
+ # It would be better to make this an attribute of `R`, but that leads to problems since
+ # we override `__getattr__`.
+ global _r_to_sage_converter
+ _r_to_sage_converter = _setup_r_to_sage_converter()
- # This is the command that starts up your program
- # See #25806 for the --no-readline switch which fixes hangs for some
- command = "R --no-readline --vanilla --quiet",
-
- server=server,
- server_tmpdir=server_tmpdir,
-
- script_subdirectory = script_subdirectory,
-
- # If this is true, then whenever the user presses Control-C to
- # interrupt a calculation, the whole interface is restarted.
- restart_on_ctrlc = False,
-
- # If true, print out a message when starting
- # up the command when you first send a command
- # to this interface.
- verbose_start = False,
-
- logfile=logfile,
-
- # If an input is longer than this number of characters, then
- # try to switch to outputting to a file.
- eval_using_file_cutoff=1024)
-
- self.__seq = 0
- self.__var_store_len = 0
- self.__init_list_length = init_list_length
- self._prompt_wait = [self._prompt]
self._seed = seed
+ self._start()
def set_seed(self, seed=None):
"""
@@ -391,14 +508,10 @@ class R(ExtraTabCompletion, Expect):
sage: r = R()
sage: r._start()
"""
- Expect._start(self)
-
# width is line width, what's a good value? maximum is 10000!
# pager needed to replace help view from less to printout
# option device= is for plotting, is set to x11, NULL would be better?
- self._change_prompt(PROMPT)
- self.eval('options(prompt=\"%s\",continue=\"%s\", width=100,pager="cat",device="png")'%(PROMPT, PROMPT))
- self.expect().expect(PROMPT)
+ self.eval('options(width=100,pager="cat",device="png")')
self.eval('options(repos="%s")'%RRepositoryURL)
self.eval('options(CRAN="%s")'%RRepositoryURL)
@@ -669,22 +782,17 @@ class R(ExtraTabCompletion, Expect):
...
ImportError: ...
"""
- ret = self.eval('require("%s")' % library_name)
- if six.PY2:
- try:
- ret = ret.decode('utf-8')
- except UnicodeDecodeError:
- ret = ret.decode('latin-1')
- # try hard to parse the message string in a locale-independent way
- if ' library(' in ret: # locale-independent key-word
- raise ImportError("%s"%ret)
+ if robjects.packages.isinstalled(library_name):
+ robjects.packages.importr(library_name)
else:
- try:
- # We need to rebuild keywords!
- del self.__tab_completion
- except AttributeError:
- pass
- self._tab_completion(verbose=False, use_disk_cache=False)
+ raise ImportError("R library {} not installed".format(library_name))
+
+ try:
+ # We need to rebuild keywords!
+ del self.__tab_completion
+ except AttributeError:
+ pass
+ self._tab_completion(verbose=False, use_disk_cache=False)
require = library #overwrites require
@@ -789,17 +897,24 @@ class R(ExtraTabCompletion, Expect):
EXAMPLES::
sage: r.help('c')
- c package:base R Documentation
+ title
+ -----
+ <BLANKLINE>
+ Combine Values into a Vector or List
+ <BLANKLINE>
+ name
+ ----
+ <BLANKLINE>
+ c
...
-
- .. note::
-
- This is similar to typing r.command?.
"""
- s = self.eval('help("%s")'%command).strip() # ?cmd is only an unsafe shortcut
+ s = robjects.help.pages(command)[0].to_docstring()
+
+ # TODO what is this for?
import sage.plot.plot
if sage.plot.plot.EMBEDDED_MODE:
s = s.replace('_\x08','')
+
return HelpExpression(s)
def _assign_symbol(self):
@@ -914,9 +1029,19 @@ class R(ExtraTabCompletion, Expect):
'[1] 5'
"""
cmd = '%s <- %s'%(var,value)
- out = self.eval(cmd)
- if out.find("error") != -1:
- raise TypeError("Error executing code in R\nCODE:\n\t%s\nR ERROR:\n\t%s"%(cmd, out))
+ # FIXME this is how it behaved before since the output was only compared to 'error'
+ # while the actual error message started with an upper-case 'Error'.
+ # The doctests rely on this when doing `loads(dumps(r('"abc"')))` which will load
+ # simply `"abc"` which will then again be set as `sage0 <- abc` (notice the missing
+ # quotes). The test will pass anyway because the identifier is reused for some reason.
+ # That means `sage0` will already be "abc" from the first `r('"abc"')` call.
+ from rpy2.rinterface import RRuntimeWarning, RRuntimeError
+ import warnings
+ warnings.filterwarnings("ignore", category = RRuntimeWarning)
+ try:
+ out = self.eval(cmd)
+ except RRuntimeError:
+ pass
def get(self, var):
"""
@@ -934,9 +1059,20 @@ class R(ExtraTabCompletion, Expect):
sage: r.get('a')
'[1] 2'
"""
- s = self.eval('%s'%var)
- #return self._remove_indices_re.sub("", s).strip()
- return s
+ # FIXME again, this is how it behaved before. The doctest `L.hom(r, base_morphism=phi)`
+ # in sage/rings/function_field/function_field.py relies on this. It somehow ends up
+ # requesting a non-existant r object resulting in
+ # `RRuntimeError: Error in (function (expr, envir = parent.frame(), enclos = if (is.list(envir) || :
+ # object 'sage2' not found`
+ # I haven't figured out how or why it does that.
+ from rpy2.rinterface import RRuntimeWarning, RRuntimeError
+ import warnings
+ warnings.filterwarnings("ignore", category = RRuntimeWarning)
+ try:
+ s = self.eval('%s'%var)
+ return s
+ except RRuntimeError:
+ return ''
def na(self):
"""
@@ -966,7 +1102,12 @@ class R(ExtraTabCompletion, Expect):
sage: dummy = r._tab_completion(use_disk_cache=False) #clean doctest
sage: r.completions('tes')
- ['testInheritedMethods', 'testPlatformEquivalence', 'testVirtual']
+ ['testInheritedMethods',
+ 'testInstalledBasic',
+ 'testInstalledPackage',
+ 'testInstalledPackages',
+ 'testPlatformEquivalence',
+ 'testVirtual']
"""
return [name for name in self._tab_completion() if name[:len(s)] == s]
@@ -986,8 +1127,7 @@ class R(ExtraTabCompletion, Expect):
"""
v = RBaseCommands
- ll = self.eval('dput(search())') # loaded libs
- ll = self.convert_r_list(ll)
+ ll = self('search()')._sage_() # loaded libs
for lib in ll:
if lib in RFilteredPackages:
@@ -996,9 +1136,7 @@ class R(ExtraTabCompletion, Expect):
if lib.find("package:") != 0:
continue #only packages
- raw = self.eval('dput(objects("%s"))'%lib)
- raw = self.convert_r_list(raw)
- raw = [x.replace(".","_") for x in raw]
+ raw = self('objects("%s")'%lib)._sage_()
#TODO are there others? many of them are shortcuts or
#should be done on another level, like selections in lists
@@ -1123,24 +1261,6 @@ class R(ExtraTabCompletion, Expect):
RFunction(self, 'plot')(*args, **kwds)
return RFunction(self, 'dev.off')()
- def _strip_prompt(self, code):
- """
- Remove the standard R prompt from the beginning of lines in code.
-
- INPUT:
-
- - code -- a string
-
- OUTPUT: a string
-
- EXAMPLES::
-
- sage: s = '> a <- 2\n> b <- 3'
- sage: r._strip_prompt(s)
- ' a <- 2\n b <- 3'
- """
- return prompt_re.sub("", code)
-
def eval(self, code, globals=None, locals=None, synchronize=True, *args, **kwds):
"""
Evaluates a command inside the R interpreter and returns the output
@@ -1151,9 +1271,8 @@ class R(ExtraTabCompletion, Expect):
sage: r.eval('1+1')
'[1] 2'
"""
- # TODO split code at ";" outside of quotes and send them as individual
- # lines without ";".
- return Expect.eval(self, code, synchronize=synchronize, *args, **kwds)
+ return str(robjects.r(code)).rstrip()
+
def _r_to_sage_name(self, s):
"""
@@ -1255,16 +1374,8 @@ class R(ExtraTabCompletion, Expect):
self.execute('setwd(%r)' % dir)
-# patterns for _sage_()
-rel_re_param = re.compile(r'\s([\w\.]+)\s=')
-rel_re_range = re.compile(r'([\d]+):([\d]+)')
-rel_re_integer = re.compile(r'([^\d])([\d]+)L')
-rel_re_terms = re.compile(r'terms\s*=\s*(.*?),')
-rel_re_call = re.compile(r'call\s*=\s*(.*?)\),')
-
-
@instancedoc
-class RElement(ExtraTabCompletion, ExpectElement):
+class RElement(ExtraTabCompletion, InterfaceElement):
def _tab_completion(self):
"""
@@ -1315,7 +1426,7 @@ class RElement(ExtraTabCompletion, ExpectElement):
sage: len(x)
5
"""
- return int(self.parent().eval('dput(length(%s))'%self.name())[:-1] )
+ return self.parent()('length(%s)'%self.name())._sage_()
def __getattr__(self, attrname):
"""
@@ -1777,95 +1888,9 @@ class RElement(ExtraTabCompletion, ExpectElement):
self._check_valid()
P = self.parent()
- # This is the core of the trick: using dput
- # dput prints out the internal structure of R's data elements
- # options via .deparseOpts(control=...)
- # TODO: dput also works with a file, if things get huge!
- # [[However, using a file for output often isn't necessary
- # since pipe buffering works pretty well for output.
- # That said, benchmark this. -- William Stein]]
- exp = P.eval('dput(%s)'%self.name())
-
- # Preprocess expression
- # example what this could be:
- # structure(list(statistic = structure(0.233549683248457, .Names = "t"),
- # parameter = structure(5.58461538461538, .Names = "df"), p.value = 0.823657802106985,
- # conf.int = structure(c(-2.41722062247400, 2.91722062247400
- # ), conf.level = 0.95), estimate = structure(c(2.75, 2.5), .Names = c("mean of x",
- # "mean of y")), null.value = structure(0, .Names = "difference in means"),
- # alternative = "two.sided", method = "Welch Two Sample t-test",
- # data.name = "c(1, 2, 3, 5) and c(1, 2, 3, 4)"), .Names = c("statistic",
- # "parameter", "p.value", "conf.int", "estimate", "null.value",
- # "alternative", "method", "data.name"), class = "htest")
-
- # R's structure (from help):
- # structure(.Data, ...)
- # .Data: an object which will have various attributes attached to it.
- # ...: attributes, specified in 'tag=value' form, which will be
- # attached to data.
- #For historical reasons (these names are used when deparsing),
- # attributes '".Dim"', '".Dimnames"', '".Names"', '".Tsp"' and
- # '".Label"' are renamed to '"dim"', '"dimnames"', '"names"',
- # '"tsp"' and '"levels"'.
-
-
-
- # we want this in a single line
- exp.replace('\n','')
- exp = "".join(exp.split("\n"))
-
- # python compatible parameters
- exp = rel_re_param.sub(self._subs_dots, exp)
-
- # Rename class since it is a Python keyword
- exp = re.sub(' class = ', ' _r_class = ',exp)
-
- # Change 'structure' to '_r_structure'
- # TODO: check that we are outside of quotes ""
- exp = re.sub(r' structure\(', ' _r_structure(', exp)
- exp = re.sub(r'^structure\(', '_r_structure(', exp) # special case
-
- # Change 'list' to '_r_list'
- exp = re.sub(r' list\(', ' _r_list(', exp)
- exp = re.sub(r'\(list\(', '(_r_list(', exp)
-
- # Change 'a:b' to 'range(a,b+1)'
- exp = rel_re_range.sub(self._subs_range, exp)
-
- # Change 'dL' to 'Integer(d)'
- exp = rel_re_integer.sub(self._subs_integer, exp)
-
- # Wrap the right hand side of terms = ... in quotes since it
- # has a ~ in it.
- exp = rel_re_terms.sub(r'terms = "\1",', exp)
-
-
- # Change call = ..., to call = "...",
- exp = rel_re_call.sub(r'call = "\1",', exp)
-
- # seems to work for
- # rr = r.summary(r.princomp(r.matrix(r.c(1,2,3,4,3,4,1,2,2),4)))
- # rr._sage_()
- # but the call expression get's evaluated. why?!? TODO
-
-
- # translation:
- # c is an ordered list
- # list is a dictionary (where _Names give the entries names.
- # map entries in names to (value, name) in each entry?
- # structure is .. see above .. structure(DATA,**kw)
- # TODO: thinking of just replacing c( with ( to get a long tuple?
-
-
- exp = self._convert_nested_r_list(exp)
-
- # Set up the globals
- globs = {'NA':None, 'NULL':None, 'FALSE':False, 'TRUE':True,
- '_r_list':self._r_list, '_r_structure':self._r_structure,
- 'Integer':sage.rings.integer.Integer,
- 'character':str}
-
- return eval(exp, globs, globs)
+ with localconverter(_r_to_sage_converter) as cv:
+ parsed = robjects.r(self.name())
+ return parsed
def _latex_(self):
@@ -1893,7 +1918,7 @@ class RElement(ExtraTabCompletion, ExpectElement):
@instancedoc
-class RFunctionElement(FunctionElement):
+class RFunctionElement(InterfaceFunctionElement):
def __reduce__(self):
"""
EXAMPLES::
@@ -1917,9 +1942,16 @@ class RFunctionElement(FunctionElement):
sage: a = r([1,2,3])
sage: length = a.length
sage: print(length.__doc__)
- length package:base R Documentation
- ...
+ title
+ -----
+ <BLANKLINE>
+ Length of an Object
+ <BLANKLINE>
+ name
+ ----
<BLANKLINE>
+ length
+ ...
"""
M = self._obj.parent()
return M.help(self._name)
@@ -1951,7 +1983,7 @@ class RFunctionElement(FunctionElement):
@instancedoc
-class RFunction(ExpectFunction):
+class RFunction(InterfaceFunction):
def __init__(self, parent, name, r_name=None):
"""
A Function in the R interface.
@@ -2007,9 +2039,16 @@ class RFunction(ExpectFunction):
sage: length = r.length
sage: print(length.__doc__)
- length package:base R Documentation
- ...
+ title
+ -----
+ <BLANKLINE>
+ Length of an Object
<BLANKLINE>
+ name
+ ----
+ <BLANKLINE>
+ length
+ ...
"""
M = self._parent
return M.help(self._name)
diff --git a/src/sage/stats/r.py b/src/sage/stats/r.py
index cd2002559b..8a2f243901 100644
--- a/src/sage/stats/r.py
+++ b/src/sage/stats/r.py
@@ -39,12 +39,12 @@ def ttest(x,y,conf_level = 0.95, **kw):
Example::
- sage: a, b = ttest([1,2,3,4,5],[1,2,3,3.5,5.121]); a
- 0.941026372027427
+ sage: a, b = ttest([1,2,3,4,5],[1,2,3,3.5,5.121]); a # abs tol 1e-12
+ 0.9410263720274274
"""
if len(x) != len(y):
raise AttributeError("vectors x and y must be of same length")
test = myR.t_test(x,y,conf_level = conf_level, **kw)._sage_()
- t = test.get('DATA').get('p_value')
+ t = test.get('DATA').get('p.value')
return t, test