passagemath-standard-no-symbolics 10.6.31rc3__cp314-cp314-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-standard-no-symbolics might be problematic. Click here for more details.

Files changed (82) hide show
  1. passagemath_standard_no_symbolics-10.6.31rc3.data/scripts/sage-grep +5 -0
  2. passagemath_standard_no_symbolics-10.6.31rc3.data/scripts/sage-grepdoc +5 -0
  3. passagemath_standard_no_symbolics-10.6.31rc3.data/scripts/sage-list-packages +103 -0
  4. passagemath_standard_no_symbolics-10.6.31rc3.dist-info/METADATA +151 -0
  5. passagemath_standard_no_symbolics-10.6.31rc3.dist-info/RECORD +82 -0
  6. passagemath_standard_no_symbolics-10.6.31rc3.dist-info/WHEEL +6 -0
  7. passagemath_standard_no_symbolics-10.6.31rc3.dist-info/top_level.txt +1 -0
  8. sage/all.py +207 -0
  9. sage/all_cmdline.py +36 -0
  10. sage/cli/__init__.py +61 -0
  11. sage/cli/__main__.py +5 -0
  12. sage/cli/eval_cmd.py +45 -0
  13. sage/cli/eval_cmd_test.py +25 -0
  14. sage/cli/interactive_shell_cmd.py +28 -0
  15. sage/cli/notebook_cmd.py +51 -0
  16. sage/cli/notebook_cmd_test.py +39 -0
  17. sage/cli/options.py +26 -0
  18. sage/cli/run_file_cmd.py +50 -0
  19. sage/cli/version_cmd.py +26 -0
  20. sage/databases/all.py +83 -0
  21. sage/databases/cubic_hecke_db.py +1527 -0
  22. sage/dynamics/all.py +31 -0
  23. sage/dynamics/surface_dynamics_deprecation.py +32 -0
  24. sage/ext_data/kenzo/CP2.txt +45 -0
  25. sage/ext_data/kenzo/CP3.txt +349 -0
  26. sage/ext_data/kenzo/CP4.txt +4774 -0
  27. sage/ext_data/kenzo/README.txt +49 -0
  28. sage/ext_data/kenzo/S4.txt +20 -0
  29. sage/ext_data/mwrank/PRIMES +1 -0
  30. sage/ext_data/nbconvert/postprocess.py +48 -0
  31. sage/ext_data/nbconvert/rst_sage.tpl +99 -0
  32. sage/ext_data/nodoctest +0 -0
  33. sage/ext_data/notebook-ipython/kernel.json.in +11 -0
  34. sage/ext_data/notebook-ipython/logo-64x64.png +0 -0
  35. sage/ext_data/notebook-ipython/logo.svg +352 -0
  36. sage/ext_data/valgrind/pyalloc.supp +58 -0
  37. sage/ext_data/valgrind/sage-additional.supp +417 -0
  38. sage/ext_data/valgrind/sage.supp +43 -0
  39. sage/ext_data/valgrind/valgrind-python.supp +480 -0
  40. sage/geometry/all.py +12 -0
  41. sage/groups/matrix_gps/pickling_overrides.py +110 -0
  42. sage/homology/tests.py +66 -0
  43. sage/interacts/algebra.py +20 -0
  44. sage/interacts/all.py +25 -0
  45. sage/interacts/calculus.py +24 -0
  46. sage/interacts/fractals.py +18 -0
  47. sage/interacts/geometry.py +19 -0
  48. sage/interacts/library.py +1950 -0
  49. sage/interacts/library_cython.cpython-314-darwin.so +0 -0
  50. sage/interacts/statistics.py +19 -0
  51. sage/interfaces/axiom.py +1002 -0
  52. sage/interfaces/kash.py +834 -0
  53. sage/interfaces/lie.py +950 -0
  54. sage/interfaces/matlab.py +413 -0
  55. sage/interfaces/mupad.py +686 -0
  56. sage/interfaces/octave.py +858 -0
  57. sage/interfaces/phc.py +943 -0
  58. sage/interfaces/psage.py +189 -0
  59. sage/interfaces/qsieve.py +4 -0
  60. sage/interfaces/r.py +2096 -0
  61. sage/interfaces/read_data.py +46 -0
  62. sage/interfaces/scilab.py +576 -0
  63. sage/interfaces/tests.py +81 -0
  64. sage/libs/all.py +11 -0
  65. sage/libs/cremona/__init__.py +0 -0
  66. sage/libs/mwrank/__init__.py +0 -0
  67. sage/logic/all.py +3 -0
  68. sage/logic/booleval.py +160 -0
  69. sage/logic/boolformula.py +1490 -0
  70. sage/logic/logic.py +856 -0
  71. sage/logic/logicparser.py +696 -0
  72. sage/logic/logictable.py +272 -0
  73. sage/logic/propcalc.py +311 -0
  74. sage/misc/all.py +28 -0
  75. sage/misc/lazy_attribute.pyi +11 -0
  76. sage/rings/all.py +48 -0
  77. sage/rings/commutative_algebra.py +38 -0
  78. sage/rings/finite_rings/all.py +21 -0
  79. sage/rings/numbers_abc.py +58 -0
  80. sage/rings/polynomial/all.py +22 -0
  81. sage/rings/polynomial/convolution.py +421 -0
  82. sage/symbolic/all__sagemath_standard_no_symbolics.py +0 -0
sage/interfaces/r.py ADDED
@@ -0,0 +1,2096 @@
1
+ # sage.doctest: needs rpy2
2
+ r"""
3
+ Interfaces to R
4
+
5
+ This is the reference to the Sagemath R interface, usable from any
6
+ Sage program.
7
+
8
+ The %r interface creating an R cell in the sage
9
+ notebook is described in the Notebook manual.
10
+
11
+ The %R and %%R interface creating an R line or an R cell in the
12
+ Jupyter notebook are briefly described at the end of this page. This
13
+ documentation will be expanded and placed in the Jupyter notebook
14
+ manual when this manual exists.
15
+
16
+ The following examples try to follow "An Introduction to R" which can
17
+ be found at http://cran.r-project.org/doc/manuals/R-intro.html .
18
+
19
+ EXAMPLES:
20
+
21
+ Simple manipulations; numbers and vectors
22
+
23
+ The simplest data structure in R is the numeric vector which
24
+ consists of an ordered collection of numbers. To create a
25
+ vector named `x` using the R interface in Sage, you pass the
26
+ R interpreter object a list or tuple of numbers::
27
+
28
+ sage: x = r([10.4,5.6,3.1,6.4,21.7]); x
29
+ [1] 10.4 5.6 3.1 6.4 21.7
30
+
31
+ You can invert elements of a vector x in R by using the
32
+ invert operator or by doing 1/x::
33
+
34
+ sage: ~x
35
+ [1] 0.09615385 0.17857143 0.32258065 0.15625000 0.04608295
36
+ sage: 1/x
37
+ [1] 0.09615385 0.17857143 0.32258065 0.15625000 0.04608295
38
+
39
+ The following assignment creates a vector `y` with 11 entries which
40
+ consists of two copies of `x` with a 0 in between::
41
+
42
+ sage: y = r([x,0,x]); y
43
+ [1] 10.4 5.6 3.1 6.4 21.7 0.0 10.4 5.6 3.1 6.4 21.7
44
+
45
+ Vector Arithmetic
46
+
47
+ The following command generates a new vector `v` of length 11 constructed
48
+ by adding together (element by element) `2x` repeated 2.2 times, `y`
49
+ repeated just once, and 1 repeated 11 times::
50
+
51
+ sage: v = 2*x+y+1; v
52
+ [1] 32.2 17.8 10.3 20.2 66.1 21.8 22.6 12.8 16.9 50.8 43.5
53
+
54
+ One can compute the sum of the elements of an R vector in the following
55
+ two ways::
56
+
57
+ sage: sum(x)
58
+ [1] 47.2
59
+ sage: x.sum()
60
+ [1] 47.2
61
+
62
+ One can calculate the sample variance of a list of numbers::
63
+
64
+ sage: ((x-x.mean())^2/(x.length()-1)).sum()
65
+ [1] 53.853
66
+ sage: x.var()
67
+ [1] 53.853
68
+
69
+ sage: x.sort()
70
+ [1] 3.1 5.6 6.4 10.4 21.7
71
+ sage: x.min()
72
+ [1] 3.1
73
+ sage: x.max()
74
+ [1] 21.7
75
+ sage: x
76
+ [1] 10.4 5.6 3.1 6.4 21.7
77
+
78
+ sage: r(-17).sqrt()
79
+ [1] NaN
80
+ sage: r('-17+0i').sqrt()
81
+ [1] 0+4.123106i
82
+
83
+ Generating an arithmetic sequence::
84
+
85
+ sage: r('1:10')
86
+ [1] 1 2 3 4 5 6 7 8 9 10
87
+
88
+ Because ``from`` is a keyword in Python, it can't be used
89
+ as a keyword argument. Instead, ``from_`` can be passed, and
90
+ R will recognize it as the correct thing::
91
+
92
+ sage: r.seq(length=10, from_=-1, by=.2)
93
+ [1] -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8
94
+
95
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
96
+ sage: x.rep(2)
97
+ [1] 10.4 5.6 3.1 6.4 21.7 10.4 5.6 3.1 6.4 21.7
98
+ sage: x.rep(times=2)
99
+ [1] 10.4 5.6 3.1 6.4 21.7 10.4 5.6 3.1 6.4 21.7
100
+ sage: x.rep(each=2)
101
+ [1] 10.4 10.4 5.6 5.6 3.1 3.1 6.4 6.4 21.7 21.7
102
+
103
+ Missing Values::
104
+
105
+ sage: na = r('NA')
106
+ sage: z = r([1,2,3,na])
107
+ sage: z
108
+ [1] 1 2 3 NA
109
+ sage: ind = r.is_na(z)
110
+ sage: ind
111
+ [1] FALSE FALSE FALSE TRUE
112
+ sage: zero = r(0)
113
+ sage: zero / zero
114
+ [1] NaN
115
+ sage: inf = r('Inf')
116
+ sage: inf-inf
117
+ [1] NaN
118
+ sage: r.is_na(inf)
119
+ [1] FALSE
120
+ sage: r.is_na(inf-inf)
121
+ [1] TRUE
122
+ sage: r.is_na(zero/zero)
123
+ [1] TRUE
124
+ sage: r.is_na(na)
125
+ [1] TRUE
126
+ sage: r.is_nan(inf-inf)
127
+ [1] TRUE
128
+ sage: r.is_nan(zero/zero)
129
+ [1] TRUE
130
+ sage: r.is_nan(na)
131
+ [1] FALSE
132
+
133
+
134
+ Character Vectors::
135
+
136
+ sage: labs = r.paste('c("X","Y")', '1:10', sep='""'); labs
137
+ [1] "X1" "Y2" "X3" "Y4" "X5" "Y6" "X7" "Y8" "X9" "Y10"
138
+
139
+
140
+ Index vectors; selecting and modifying subsets of a data set::
141
+
142
+ sage: na = r('NA')
143
+ sage: x = r([10.4,5.6,3.1,6.4,21.7,na]); x
144
+ [1] 10.4 5.6 3.1 6.4 21.7 NA
145
+ sage: x['!is.na(self)']
146
+ [1] 10.4 5.6 3.1 6.4 21.7
147
+
148
+ sage: x = r([10.4,5.6,3.1,6.4,21.7,na]); x
149
+ [1] 10.4 5.6 3.1 6.4 21.7 NA
150
+ sage: (x+1)['(!is.na(self)) & self>0']
151
+ [1] 11.4 6.6 4.1 7.4 22.7
152
+ sage: x = r([10.4,-2,3.1,-0.5,21.7,na]); x
153
+ [1] 10.4 -2.0 3.1 -0.5 21.7 NA
154
+ sage: (x+1)['(!is.na(self)) & self>0']
155
+ [1] 11.4 4.1 0.5 22.7
156
+
157
+ Distributions::
158
+
159
+ sage: r.options(width='60')
160
+ $width
161
+ [1] 80
162
+
163
+ sage: rr = r.dnorm(r.seq(-3,3,0.1))
164
+ sage: rr
165
+ [1] 0.004431848 0.005952532 0.007915452 0.010420935
166
+ [5] 0.013582969 0.017528300 0.022394530 0.028327038
167
+ [9] 0.035474593 0.043983596 0.053990967 0.065615815
168
+ [13] 0.078950158 0.094049077 0.110920835 0.129517596
169
+ [17] 0.149727466 0.171368592 0.194186055 0.217852177
170
+ [21] 0.241970725 0.266085250 0.289691553 0.312253933
171
+ [25] 0.333224603 0.352065327 0.368270140 0.381387815
172
+ [29] 0.391042694 0.396952547 0.398942280 0.396952547
173
+ [33] 0.391042694 0.381387815 0.368270140 0.352065327
174
+ [37] 0.333224603 0.312253933 0.289691553 0.266085250
175
+ [41] 0.241970725 0.217852177 0.194186055 0.171368592
176
+ [45] 0.149727466 0.129517596 0.110920835 0.094049077
177
+ [49] 0.078950158 0.065615815 0.053990967 0.043983596
178
+ [53] 0.035474593 0.028327038 0.022394530 0.017528300
179
+ [57] 0.013582969 0.010420935 0.007915452 0.005952532
180
+ [61] 0.004431848
181
+
182
+ Convert R Data Structures to Python/Sage::
183
+
184
+ sage: rr = r.dnorm(r.seq(-3,3,0.1))
185
+ sage: sum(rr._sage_())
186
+ 9.9772125168981...
187
+
188
+ Or you get a dictionary to be able to access all the information::
189
+
190
+ sage: rs = r.summary(r.c(1,4,3,4,3,2,5,1))
191
+ sage: rs
192
+ Min. 1st Qu. Median Mean 3rd Qu. Max.
193
+ 1.000 1.750 3.000 2.875 4.000 5.000
194
+ sage: d = rs._sage_()
195
+ sage: d['DATA']
196
+ [1, 1.75, 3, 2.875, 4, 5]
197
+ sage: d['_Names']
198
+ ['Min.', '1st Qu.', 'Median', 'Mean', '3rd Qu.', 'Max.']
199
+ sage: d['_r_class']
200
+ ['summaryDefault', 'table']
201
+
202
+ It is also possible to access the plotting capabilities of R
203
+ through Sage. For more information see the documentation of
204
+ r.plot() or r.png().
205
+
206
+ THE JUPYTER NOTEBOOK INTERFACE (work in progress).
207
+
208
+ The %r interface described in the Sage notebook manual is not useful
209
+ in the Jupyter notebook : it creates a inferior R interpreter which
210
+ cannot be escaped.
211
+
212
+ The RPy2 library allows the creation of an R cell in the Jupyter
213
+ notebook analogous to the %r escape in command line or %r cell in a
214
+ Sage notebook.
215
+
216
+ The interface is loaded by a cell containing the sole code:
217
+
218
+ "%load_ext rpy2.ipython"
219
+
220
+ After execution of this code, the %R and %%R magics are available:
221
+
222
+ - %R allows the execution of a single line of R code. Data exchange is
223
+ possible via the -i and -o options. Do "%R?" in a standalone cell
224
+ to get the documentation.
225
+
226
+ - %%R allows the execution in R of the whole text of a cell, with
227
+ similar options (do "%%R?" in a standalone cell for
228
+ documentation).
229
+
230
+ A few important points must be noted:
231
+
232
+ - The R interpreter launched by this interface IS (currently)
233
+ DIFFERENT from the R interpreter used br other r... functions.
234
+
235
+ - Data exchanged via the -i and -o options have a format DIFFERENT
236
+ from the format used by the r... functions (RPy2 mostly uses arrays,
237
+ and bugs the user to use the pandas Python package).
238
+
239
+ - R graphics are (beautifully) displayed in output cells, but are not
240
+ directly importable. You have to save them as .png, .pdf or .svg
241
+ files and import them in Sage for further use.
242
+
243
+ In its current incarnation, this interface is mostly useful to
244
+ statisticians needing Sage for a few symbolic computations but mostly
245
+ using R for applied work.
246
+
247
+ AUTHORS:
248
+
249
+ - Mike Hansen (2007-11-01)
250
+ - William Stein (2008-04-19)
251
+ - Harald Schilly (2008-03-20)
252
+ - Mike Hansen (2008-04-19)
253
+ - Emmanuel Charpentier (2015-12-12, RPy2 interface)
254
+ """
255
+
256
+ # ************************************************************************
257
+ #
258
+ # Copyright (C) 2007 William Stein <wstein@gmail.com>
259
+ # 2007 Mike Hansen <mhansen@gmail.com>
260
+ # 2008 Harald Schilly <harald.schilly@gmail.com>
261
+ #
262
+ # Distributed under the terms of the GNU General Public License (GPL)
263
+ #
264
+ # https://www.gnu.org/licenses/
265
+ #
266
+ # ************************************************************************
267
+ import os
268
+
269
+ from .interface import Interface, InterfaceElement, InterfaceFunction, InterfaceFunctionElement
270
+ from sage.env import DOT_SAGE
271
+ import re
272
+ from sage.structure.element import parent
273
+ from sage.interfaces.tab_completion import ExtraTabCompletion
274
+ from sage.misc.instancedoc import instancedoc
275
+
276
+ # see the _lazy_init for some reasoning behind the lazy imports
277
+ from sage.misc.lazy_import import lazy_import
278
+ from sage.features import PythonModule
279
+
280
+ rpy2_feature = PythonModule('rpy2', spkg='rpy2', type='standard')
281
+
282
+ lazy_import("rpy2", "robjects", feature=rpy2_feature)
283
+ lazy_import("rpy2.robjects", "packages", "rpy2_packages", feature=rpy2_feature)
284
+ lazy_import("rpy2.robjects.conversion", ["localconverter", "Converter"], feature=rpy2_feature)
285
+
286
+ # for help page fetching
287
+ lazy_import("rpy2.robjects.help", "Package", feature=rpy2_feature)
288
+ lazy_import("rpy2", "rinterface", feature=rpy2_feature)
289
+
290
+
291
+ COMMANDS_CACHE = '%s/r_commandlist.sobj' % DOT_SAGE
292
+
293
+ # there is a mirror network, but lets take #1 for now
294
+ RRepositoryURL = "http://cran.r-project.org/"
295
+ RFilteredPackages = ['.GlobalEnv']
296
+
297
+ # crosscheck with https://svn.r-project.org/R/trunk/src/main/names.c
298
+ # but package:base should cover this. i think.
299
+ RBaseCommands = ['c', "NULL", "NA", "True", "False", "Inf", "NaN"]
300
+
301
+
302
+ def _setup_r_to_sage_converter():
303
+ """
304
+ Set up a the converter used to convert from rpy2's
305
+ representation of R objects to the one sage expects.
306
+
307
+ EXAMPLES:
308
+
309
+ Simple numeric values are represented as vectors in R. So `1`
310
+ would actually be an array of length 1. We convert all vectors of
311
+ length 1 to simple values, whether or not they "originally" were
312
+ simple values or not::
313
+
314
+ sage: r([42]).sage()
315
+ 42
316
+
317
+ sage: r(42).sage()
318
+ 42
319
+
320
+ sage: r('c("foo")').sage()
321
+ 'foo'
322
+
323
+ Arrays of length greater than one are treated normally::
324
+
325
+ sage: r([42, 43]).sage()
326
+ [42, 43]
327
+
328
+ We also convert all numeric values to integers if that is possible without
329
+ loss of precision::
330
+
331
+ sage: type(r([1.0]).sage()) == int
332
+ True
333
+
334
+ sage: r([1.0, 42.5]).sage()
335
+ [1, 42.5]
336
+
337
+ Matrices are converted to sage matrices::
338
+
339
+ sage: r('matrix(c(2,4,3,1,5,7), nrow=2, ncol=3)').sage()
340
+ [2 3 5]
341
+ [4 1 7]
342
+
343
+ More complex r structures are represented by dictionaries::
344
+
345
+ sage: r.summary(1).sage()
346
+ {'DATA': [1, 1, 1, 1, 1, 1],
347
+ '_Names': ['Min.', '1st Qu.', 'Median', 'Mean', '3rd Qu.', 'Max.'],
348
+ '_r_class': ['summaryDefault', 'table']}
349
+
350
+ sage: r.options(width='60').sage()
351
+ {'DATA': {'width': 60}, '_Names': 'width'}
352
+
353
+ The conversion can handle "not a number", infinity, imaginary values and
354
+ missing values::
355
+
356
+ sage: r(-17).sqrt().sage()
357
+ nan
358
+ sage: r('-17+0i').sqrt().sage()
359
+ 4.123105625617661j
360
+ sage: r('NA').sage()
361
+ NA
362
+ sage: inf = r('Inf'); inf.sage()
363
+ inf
364
+
365
+ Character Vectors are represented by regular python arrays::
366
+
367
+ sage: labs = r.paste('c("X","Y")', '1:10', sep='""'); labs.sage()
368
+ ['X1', 'Y2', 'X3', 'Y4', 'X5', 'Y6', 'X7', 'Y8', 'X9', 'Y10']
369
+ """
370
+ from rpy2.rinterface import SexpVector, ListSexpVector, FloatSexpVector
371
+
372
+ # convert rpy2's representation of r objects to the one sage expects (as defined by the old
373
+ # expect interface)
374
+ cv = Converter('r to sage converter')
375
+
376
+ # support rpy version 2 and 3
377
+ try:
378
+ rpy2py = cv.rpy2py
379
+ except AttributeError:
380
+ rpy2py = cv.ri2py
381
+
382
+ # fallback
383
+ rpy2py.register(object, lambda obj: obj)
384
+
385
+ def float_to_int_if_possible(f):
386
+ # First, round the float to at most 15 significant places.
387
+ # This is what R does by default when using `dput`. It prevents
388
+ # platform-specific fluctuations.
389
+ f = float('%.15g' % f)
390
+ # Preserve the behaviour of the old r parser, e.g. return 1 instead of 1.0
391
+ float_or_int = int(f) if isinstance(f, int) or f.is_integer() else f
392
+ return float_or_int
393
+ rpy2py.register(float, float_to_int_if_possible)
394
+
395
+ def list_to_singleton_if_possible(l):
396
+ if len(l) == 1:
397
+ return l[0]
398
+ else:
399
+ return l
400
+
401
+ def _vector(vec):
402
+ attrs = vec.list_attrs()
403
+ # Recursive calls have to be made explicitly
404
+ # https://bitbucket.org/rpy2/rpy2/issues/363/custom-converters-are-not-applied
405
+ data = list_to_singleton_if_possible([rpy2py(val) for val in vec])
406
+ rclass = list(vec.do_slot('class')) if 'class' in attrs else vec.rclass
407
+
408
+ if 'names' in attrs:
409
+ # separate names and values, call rpy2py recursively to convert elements
410
+ names = list_to_singleton_if_possible(list(vec.do_slot('names')))
411
+ return {
412
+ 'DATA': data,
413
+ '_Names': names,
414
+ '_r_class': rclass,
415
+ }
416
+ else:
417
+ # if no names are present, convert to a normal list or a single value
418
+ return data
419
+ rpy2py.register(SexpVector, _vector)
420
+
421
+ def _matrix(mat):
422
+ if 'dim' in mat.list_attrs():
423
+ try:
424
+ from sage.matrix.constructor import matrix
425
+ dimensions = mat.do_slot("dim")
426
+ if len(dimensions) != 2:
427
+ raise NotImplementedError("Higher-dimension matrices are currently not supported")
428
+ (nrow, ncol) = dimensions
429
+ # Since R does it the other way round, we assign transposed and
430
+ # then transpose the matrix :)
431
+ m = matrix(ncol, nrow, [rpy2py(i) for i in mat])
432
+ return m.transpose()
433
+ except TypeError:
434
+ pass
435
+ else:
436
+ return _vector(mat)
437
+ rpy2py.register(FloatSexpVector, _matrix)
438
+
439
+ def _list_vector(vec):
440
+ # we have a R list (vector of arbitrary elements)
441
+ attrs = vec.list_attrs()
442
+ names = vec.do_slot('names')
443
+ values = [rpy2py(val) for val in vec]
444
+ rclass = list(vec.do_slot('class')) if 'class' in attrs else vec.rclass
445
+ data = zip(names, values)
446
+ return {
447
+ 'DATA': dict(data),
448
+ '_Names': rpy2py(names),
449
+ # We don't give the rclass here because the old expect interface
450
+ # didn't do that either and we want to maintain compatibility.
451
+ }
452
+ rpy2py.register(ListSexpVector, _list_vector)
453
+
454
+ return cv
455
+
456
+
457
+ class R(ExtraTabCompletion, Interface):
458
+ def __init__(self,
459
+ maxread=None,
460
+ logfile=None,
461
+ init_list_length=1024,
462
+ seed=None):
463
+ """
464
+ An interface to the R interpreter.
465
+
466
+ R is a comprehensive collection of methods for statistics,
467
+ modelling, bioinformatics, data analysis and much more.
468
+ For more details, see http://www.r-project.org/about.html
469
+
470
+ Resources:
471
+
472
+ * http://r-project.org/ provides more information about R.
473
+ * http://rseek.org/ R's own search engine.
474
+
475
+ EXAMPLES::
476
+
477
+ sage: r.summary(r.c(1,2,3,111,2,3,2,3,2,5,4))
478
+ Min. 1st Qu. Median Mean 3rd Qu. Max.
479
+ 1.00 2.00 3.00 12.55 3.50 111.00
480
+
481
+ TESTS::
482
+
483
+ sage: r == loads(dumps(r))
484
+ True
485
+ """
486
+ Interface.__init__(
487
+ self,
488
+ name='r', # The capitalized version of this is used for printing.
489
+ )
490
+ self._seed = seed
491
+ self._initialized = False # done lazily
492
+
493
+ def _lazy_init(self):
494
+ """
495
+ Initialize the R interpreter.
496
+
497
+ This will set the initial options and implicitly (through
498
+ lazy_import) import rpy2 if it is not already imported.
499
+
500
+ Importing rpy2 takes something in the order of hundreds of milliseconds.
501
+ It also takes tens of megabytes of RAM. Since an instance of R is
502
+ assigned to the global variable `r` at sage startup, it is important to
503
+ be as lazy as possible here.
504
+ For some discussion, see https://bitbucket.org/rpy2/rpy2/issues/490.
505
+
506
+ Also, importing rpy2 too early (e.g. before numpy) can cause issues with
507
+ the blas implementation that is used.
508
+ For details, see https://bitbucket.org/rpy2/rpy2/issues/491.
509
+
510
+ TESTS:
511
+
512
+ Initialization happens on eval::
513
+
514
+ sage: my_r = R()
515
+ sage: my_r._initialized
516
+ False
517
+ sage: my_r(42) # indirect doctest
518
+ [1] 42
519
+ sage: my_r._initialized
520
+ True
521
+
522
+ And on package import::
523
+
524
+ sage: my_r = R()
525
+ sage: my_r._initialized
526
+ False
527
+ sage: my_r.library('grid')
528
+ sage: my_r._initialized
529
+ True
530
+
531
+ And when fetching help pages::
532
+
533
+ sage: my_r = R()
534
+ sage: my_r._initialized
535
+ False
536
+ sage: _ = my_r.help('c')
537
+ sage: my_r._initialized
538
+ True
539
+ """
540
+ if not self._initialized:
541
+ # Set this to True *before* the call to start, since that will call eval() which will in turn call this function.
542
+ # Setting this to True early prevents infinite recursion.
543
+ self._initialized = True
544
+ self._r_to_sage_converter = _setup_r_to_sage_converter()
545
+ self._start()
546
+
547
+ def _coerce_impl(self, x, use_special=True):
548
+ """
549
+ TESTS:
550
+
551
+ Check conversion of Booleans (:issue:`28705`)::
552
+
553
+ sage: repr(r(True)) == r._true_symbol() # indirect doctest
554
+ True
555
+ """
556
+ # We overwrite _coerce_impl here because r._true_symbol() and
557
+ # r._false_symbol() are output strings that start with "[1] " and thus
558
+ # cannot be used as input
559
+ if isinstance(x, bool):
560
+ return self('TRUE' if x else 'FALSE')
561
+ return super()._coerce_impl(x, use_special=use_special)
562
+
563
+ def set_seed(self, seed=None):
564
+ """
565
+ Set the seed for R interpreter.
566
+
567
+ The seed should be an integer.
568
+
569
+ EXAMPLES::
570
+
571
+ sage: r = R()
572
+ sage: r.set_seed(1)
573
+ 1
574
+ sage: r.sample("1:10", 5) # random
575
+ [1] 3 4 5 7 2
576
+ """
577
+ if seed is None:
578
+ seed = self.rand_seed()
579
+ self.eval('set.seed(%d)' % seed)
580
+ self._seed = seed
581
+ return seed
582
+
583
+ def _start(self):
584
+ """
585
+ Start up the R interpreter and sets the initial prompt and options.
586
+
587
+ This is called the first time the R interface is actually used.
588
+
589
+ EXAMPLES::
590
+
591
+ sage: r = R()
592
+ sage: r._start()
593
+ """
594
+ # pager needed to replace help view from less to printout
595
+ # option device= is for plotting, is set to x11, NULL would be better?
596
+ self.eval('options(pager="cat",device="png")')
597
+ self.eval('options(repos="%s")' % RRepositoryURL)
598
+ self.eval('options(CRAN="%s")' % RRepositoryURL)
599
+
600
+ # don't abort on errors, just raise them!
601
+ # necessary for non-interactive execution
602
+ self.eval('options(error = expression(NULL))')
603
+
604
+ # set random seed
605
+ self.set_seed(self._seed)
606
+
607
+ def png(self, *args, **kwds):
608
+ """
609
+ Create an R PNG device.
610
+
611
+ This should primarily be used to save an R graphic to a custom file. Note
612
+ that when using this in the notebook, one must plot in the same cell that
613
+ one creates the device. See r.plot() documentation for more information
614
+ about plotting via R in Sage.
615
+
616
+ These examples won't work on the many platforms where R still gets
617
+ built without graphics support.
618
+
619
+ EXAMPLES::
620
+
621
+ sage: filename = tmp_filename() + '.png'
622
+ sage: r.png(filename='"%s"'%filename) # optional - rgraphics
623
+ NULL
624
+ sage: x = r([1,2,3])
625
+ sage: y = r([4,5,6])
626
+ sage: r.plot(x,y) # optional - rgraphics
627
+ null device
628
+ 1
629
+ sage: import os; os.unlink(filename) # optional - rgraphics
630
+
631
+ We want to make sure that we actually can view R graphics, which happens
632
+ differently on different platforms::
633
+
634
+ sage: s = r.eval('capabilities("png")') # should be on Linux and Solaris
635
+ sage: t = r.eval('capabilities("aqua")') # should be on all supported Mac versions
636
+ sage: "TRUE" in s+t # optional - rgraphics
637
+ True
638
+ """
639
+ # Check to see if R has PNG support
640
+ s = self.eval('capabilities("png")')
641
+ t = self.eval('capabilities("aqua")')
642
+ if "TRUE" not in s + t:
643
+ raise RuntimeError("R was not compiled with PNG support")
644
+ return RFunction(self, 'png')(*args, **kwds)
645
+
646
+ def convert_r_list(self, l):
647
+ r"""
648
+ Convert an R list to a Python list.
649
+
650
+ EXAMPLES::
651
+
652
+ sage: s = 'c(".GlobalEnv", "package:stats", "package:graphics", "package:grDevices", \n"package:utils", "package:datasets", "package:methods", "Autoloads", \n"package:base")'
653
+ sage: r.convert_r_list(s)
654
+ ['.GlobalEnv',
655
+ 'package:stats',
656
+ 'package:graphics',
657
+ 'package:grDevices',
658
+ 'package:utils',
659
+ 'package:datasets',
660
+ 'package:methods',
661
+ 'Autoloads',
662
+ 'package:base']
663
+ """
664
+ # This function is only kept for legacy reasons. It was used internally
665
+ # in the old expect based interface and for some reason was made part
666
+ # of the public api.
667
+ return self(l).sage()
668
+
669
+ def install_packages(self, package_name):
670
+ """
671
+ Install an R package into Sage's R installation.
672
+
673
+ EXAMPLES::
674
+
675
+ sage: r.install_packages('aaMI') # not tested
676
+ ...
677
+ R is free software and comes with ABSOLUTELY NO WARRANTY.
678
+ You are welcome to redistribute it under certain conditions.
679
+ Type 'license()' or 'licence()' for distribution details.
680
+ ...
681
+ Please restart Sage in order to use 'aaMI'.
682
+ """
683
+ cmd = """options(repos="%s"); install.packages("%s")""" % (RRepositoryURL, package_name)
684
+ os.system("time echo '%s' | R --vanilla" % cmd)
685
+ print("Please restart Sage in order to use '%s'." % package_name)
686
+
687
+ def _repr_(self):
688
+ """
689
+ Return string representation of this R interface.
690
+
691
+ EXAMPLES::
692
+
693
+ sage: r # indirect doctest
694
+ R Interpreter
695
+ """
696
+ return 'R Interpreter'
697
+
698
+ def __reduce__(self):
699
+ """
700
+ Used in serializing an R interface.
701
+
702
+ EXAMPLES::
703
+
704
+ sage: from sage.interfaces.r import r
705
+ sage: rlr, t = r.__reduce__()
706
+ sage: rlr(*t)
707
+ R Interpreter
708
+ """
709
+ return reduce_load_R, tuple([])
710
+
711
+ def __getattr__(self, attrname):
712
+ """
713
+ Called when you get an attribute of the R interface. This
714
+ manufactures an R function, which is a Python function that
715
+ can then be called with various inputs.
716
+
717
+ EXAMPLES::
718
+
719
+ sage: c = r.c; c
720
+ c
721
+ sage: type(c)
722
+ <class 'sage.interfaces.r.RFunction'>
723
+ """
724
+ try:
725
+ # First try to get a regular python attribute. This makes it
726
+ # possible to still use attributes like _r_to_sage_converter
727
+ # internally.
728
+ self.__getattribute__(attrname)
729
+ except AttributeError:
730
+ # if there is no such attribute, get the r attribute
731
+ if attrname[:1] == "_":
732
+ raise AttributeError("Attribute {} is not allowed to start with an underscore.".format(attrname))
733
+ return RFunction(self, attrname)
734
+
735
+ def _read_in_file_command(self, filename):
736
+ r"""
737
+ Return the R command (as a string) to read in a file named
738
+ filename into the R interpreter.
739
+
740
+ EXAMPLES::
741
+
742
+ sage: r._read_in_file_command('file.txt')
743
+ 'file=file("file.txt",open="r")\nsource(file)'
744
+ """
745
+ return 'file=file("%s",open="r")\nsource(file)' % filename
746
+
747
+ def read(self, filename):
748
+ r"""
749
+ Read filename into the R interpreter by calling R's source function on a
750
+ read-only file connection.
751
+
752
+ EXAMPLES::
753
+
754
+ sage: filename = tmp_filename()
755
+ sage: f = open(filename, 'w')
756
+ sage: _ = f.write('a <- 2+2\n')
757
+ sage: f.close()
758
+ sage: r.read(filename)
759
+ sage: r.get('a')
760
+ '[1] 4'
761
+ """
762
+ self.eval(self._read_in_file_command(filename))
763
+
764
+ def _install_hints(self):
765
+ """
766
+ EXAMPLES::
767
+
768
+ sage: print(r._install_hints())
769
+ R is currently installed with Sage.
770
+ """
771
+ return "R is currently installed with Sage.\n"
772
+
773
+ def _source(self, s):
774
+ """
775
+ Return the source code of an R function as a string.
776
+
777
+ INPUT:
778
+
779
+ - ``s`` -- the name of the function as a string
780
+
781
+ EXAMPLES::
782
+
783
+ sage: print(r._source("c"))
784
+ function (...) .Primitive("c")
785
+ """
786
+ if s[-2:] == "()":
787
+ s = s[-2:]
788
+ return self.eval('%s' % s)
789
+
790
+ def source(self, s):
791
+ """
792
+ Display the R source (if possible) about the function named s.
793
+
794
+ INPUT:
795
+
796
+ - ``s`` -- string representing the function whose source code you want to see
797
+
798
+ OUTPUT: string; source code
799
+
800
+ EXAMPLES::
801
+
802
+ sage: print(r.source("c"))
803
+ function (...) .Primitive("c")
804
+ """
805
+ return self._source(s)
806
+
807
+ def version(self):
808
+ """
809
+ Return the version of R currently running.
810
+
811
+ OUTPUT: tuple of ints; string
812
+
813
+ EXAMPLES::
814
+
815
+ sage: r.version() # not tested
816
+ ((3, 0, 1), 'R version 3.0.1 (2013-05-16)')
817
+ sage: rint, rstr = r.version()
818
+ sage: rint[0] >= 3
819
+ True
820
+ sage: rstr.startswith('R version')
821
+ True
822
+ """
823
+ major_re = re.compile(r'^major\s*(\d.*?)$', re.M)
824
+ minor_re = re.compile(r'^minor\s*(\d.*?)$', re.M)
825
+ version_string_re = re.compile(r'^version.string\s*(R.*?)$', re.M)
826
+
827
+ s = self.eval('version')
828
+
829
+ major = int(major_re.findall(s)[0].strip())
830
+ minor = tuple(int(i) for i in minor_re.findall(s)[0].strip().split("."))
831
+ version_string = version_string_re.findall(s)[0].strip()
832
+
833
+ return ((major,) + minor, version_string)
834
+
835
+ def library(self, library_name):
836
+ """
837
+ Load the library library_name into the R interpreter.
838
+
839
+ This function raises an :exc:`ImportError` if the given library
840
+ is not known.
841
+
842
+ INPUT:
843
+
844
+ - ``library_name`` -- string
845
+
846
+ EXAMPLES::
847
+
848
+ sage: r.library('grid')
849
+ sage: 'grid' in r.eval('(.packages())')
850
+ True
851
+ sage: r.library('foobar')
852
+ Traceback (most recent call last):
853
+ ...
854
+ ImportError: ...
855
+ """
856
+ self._lazy_init()
857
+ if rpy2_packages.isinstalled(library_name):
858
+ rpy2_packages.importr(library_name)
859
+ else:
860
+ raise ImportError("R library {} not installed".format(library_name))
861
+
862
+ try:
863
+ # We need to rebuild keywords!
864
+ del self.__tab_completion
865
+ except AttributeError:
866
+ pass
867
+ self._tab_completion(verbose=False, use_disk_cache=False)
868
+
869
+ require = library # overwrites require
870
+
871
+ def available_packages(self):
872
+ """
873
+ Return a list of all available R package names.
874
+
875
+ This list is not necessarily sorted.
876
+
877
+ OUTPUT: list of strings
878
+
879
+ .. NOTE::
880
+
881
+ This requires an internet connection. The CRAN server is
882
+ that is checked is defined at the top of sage/interfaces/r.py.
883
+
884
+ EXAMPLES::
885
+
886
+ sage: ap = r.available_packages() # optional - internet
887
+ sage: len(ap) > 20 # optional - internet
888
+ True
889
+ """
890
+ p = self.new('available.packages("%s/src/contrib")' % RRepositoryURL)
891
+ s = str(p).splitlines()[1:]
892
+ v = [x.split()[0].strip("'") for x in s]
893
+ return v
894
+ # The following was more structural, but breaks on my machine. (stein)
895
+ # p = p._sage_()
896
+ # s = p['_Dim'][0]
897
+ # l = [[p['DATA'][i],p['DATA'][s+1+i]] for i in range(s)]
898
+ # return l
899
+
900
+ def _object_class(self):
901
+ """
902
+ Return the underlying class of elements of the R interface object.
903
+
904
+ OUTPUT: a Python class
905
+
906
+ EXAMPLES::
907
+
908
+ sage: r._object_class()
909
+ <class 'sage.interfaces.r.RElement'>
910
+ """
911
+ return RElement
912
+
913
+ def _true_symbol(self):
914
+ """
915
+ Return the symbol that represents ``True`` in R.
916
+
917
+ OUTPUT: string
918
+
919
+ EXAMPLES::
920
+
921
+ sage: r._true_symbol()
922
+ '[1] TRUE'
923
+ """
924
+ # return the string rep of truth, i.e., what the system outputs
925
+ # when you type 1==1.
926
+ return "[1] TRUE"
927
+
928
+ def _false_symbol(self):
929
+ """
930
+ Return the symbol that represents ``True`` in R.
931
+
932
+ OUTPUT: string
933
+
934
+ EXAMPLES::
935
+
936
+ sage: r._false_symbol()
937
+ '[1] FALSE'
938
+ """
939
+ # return the string rep of false, i.e., what the system outputs
940
+ # when you type 1==2.
941
+ return "[1] FALSE"
942
+
943
+ def _equality_symbol(self):
944
+ """
945
+ EXAMPLES::
946
+
947
+ sage: r._equality_symbol()
948
+ '=='
949
+ """
950
+ # return the symbol for checking equality, e.g., == or eq.
951
+ return "=="
952
+
953
+ # A replacement for rpy2's help.pages that only considers loaded packages
954
+ # (as R's help function does by default). Hopefully upstream will support
955
+ # this in the future: https://bitbucket.org/rpy2/rpy2/issues/498
956
+ def _loaded_package_pages(self, topic):
957
+ # for some reason `except` doesn't work with lazy import, so import this here
958
+ from rpy2.robjects.help import HelpNotFoundError
959
+ self._lazy_init()
960
+ res = list()
961
+
962
+ for name in rinterface.baseenv['loadedNamespaces']():
963
+ pack = Package(name)
964
+ try:
965
+ page = pack.fetch(topic)
966
+ res.append(page)
967
+ except HelpNotFoundError:
968
+ pass
969
+
970
+ return tuple(res)
971
+
972
+ def help(self, command):
973
+ """
974
+ Return help string for a given command.
975
+
976
+ INPUT:
977
+
978
+ - ``command`` -- string
979
+
980
+ OUTPUT: HelpExpression; a subclass of string whose ``__repr__``
981
+ method is ``__str__``, so it prints nicely
982
+
983
+ EXAMPLES::
984
+
985
+ sage: r.help('c')
986
+ title
987
+ -----
988
+ <BLANKLINE>
989
+ Combine Values into a Vector or List
990
+ <BLANKLINE>
991
+ name
992
+ ----
993
+ <BLANKLINE>
994
+ c
995
+ ...
996
+ """
997
+ # This is looking for the topic in all existing namespaces.
998
+ # Theoretically, there may be multiple options. We ignore that.
999
+ pages_for_topic = self._loaded_package_pages(command)
1000
+ if len(pages_for_topic) == 0:
1001
+ raise ValueError("There is no help page for the given topic")
1002
+
1003
+ s = pages_for_topic[0].to_docstring()
1004
+ return HelpExpression(s)
1005
+
1006
+ def _assign_symbol(self):
1007
+ """
1008
+ Return the symbol used in R for assignment, which is ' <- '.
1009
+
1010
+ OUTPUT: string
1011
+
1012
+ EXAMPLES::
1013
+
1014
+ sage: r._assign_symbol()
1015
+ ' <- '
1016
+ """
1017
+ return " <- "
1018
+
1019
+ def _left_list_delim(self):
1020
+ """
1021
+ Return the left delimiter for lists in R, which is 'c('.
1022
+
1023
+ OUTPUT: string
1024
+
1025
+ EXAMPLES::
1026
+
1027
+ sage: r._left_list_delim()
1028
+ 'c('
1029
+ """
1030
+ return "c("
1031
+
1032
+ def _right_list_delim(self):
1033
+ """
1034
+ Return the right delimiter for lists in R, which is 'c('.
1035
+
1036
+ OUTPUT: string
1037
+
1038
+ EXAMPLES::
1039
+
1040
+ sage: r._right_list_delim()
1041
+ ')'
1042
+ """
1043
+ return ")"
1044
+
1045
+ def console(self):
1046
+ """
1047
+ Run the R console as a separate new R process.
1048
+
1049
+ EXAMPLES::
1050
+
1051
+ sage: r.console() # not tested
1052
+ R version 2.6.1 (2007-11-26)
1053
+ Copyright (C) 2007 The R Foundation for Statistical Computing
1054
+ ISBN 3-900051-07-0
1055
+ ...
1056
+ """
1057
+ r_console()
1058
+
1059
+ def function_call(self, function, args=None, kwds=None):
1060
+ """
1061
+ Return the result of calling an R function, with given args and keyword args.
1062
+
1063
+ OUTPUT: RElement; an object in R
1064
+
1065
+ EXAMPLES::
1066
+
1067
+ sage: r.function_call('length', args=[ [1,2,3] ])
1068
+ [1] 3
1069
+ """
1070
+ args, kwds = self._convert_args_kwds(args, kwds)
1071
+ self._check_valid_function_name(function)
1072
+ return self.new("%s(%s)" % (function, ",".join([s.name() for s in args] +
1073
+ [self._sage_to_r_name(key) + '=' + kwds[key].name() for key in kwds])))
1074
+
1075
+ def call(self, function_name, *args, **kwds):
1076
+ r"""
1077
+ This is an alias for :meth:`function_call`.
1078
+
1079
+ EXAMPLES::
1080
+
1081
+ sage: r.call('length', [1,2,3])
1082
+ [1] 3
1083
+ """
1084
+ return self.function_call(function_name, args=args, kwds=kwds)
1085
+
1086
+ def _an_element_(self):
1087
+ """
1088
+ Return an element belonging to the R interpreter. This is used
1089
+ behind the scenes when doing things like comparisons, etc.
1090
+
1091
+ OUTPUT: RElement; an R element
1092
+
1093
+ EXAMPLES::
1094
+
1095
+ sage: r._an_element_()
1096
+ [1] 0
1097
+ sage: type(_)
1098
+ <class 'sage.interfaces.r.RElement'>
1099
+ """
1100
+ return self(0)
1101
+
1102
+ def set(self, var, value):
1103
+ """
1104
+ Set the variable var in R to what the string value evaluates to in R.
1105
+
1106
+ INPUT:
1107
+
1108
+ - ``var`` -- string
1109
+ - ``value`` -- string
1110
+
1111
+ EXAMPLES::
1112
+
1113
+ sage: r.set('a', '2 + 3')
1114
+ sage: r.get('a')
1115
+ '[1] 5'
1116
+ """
1117
+ _ = self.eval(f'{var} <- {value}')
1118
+
1119
+ def get(self, var):
1120
+ """
1121
+ Return the string representation of the variable var.
1122
+
1123
+ INPUT:
1124
+
1125
+ - ``var`` -- string
1126
+
1127
+ OUTPUT: string
1128
+
1129
+ EXAMPLES::
1130
+
1131
+ sage: r.set('a', 2)
1132
+ sage: r.get('a')
1133
+ '[1] 2'
1134
+ """
1135
+ return self.eval('%s' % var)
1136
+
1137
+ def na(self):
1138
+ """
1139
+ Return the NA in R.
1140
+
1141
+ OUTPUT: RElement; an element of R
1142
+
1143
+ EXAMPLES::
1144
+
1145
+ sage: r.na()
1146
+ [1] NA
1147
+ """
1148
+ return self('NA')
1149
+
1150
+ def completions(self, s):
1151
+ """
1152
+ Return all commands names that complete the command starting with the
1153
+ string s. This is like typing s[Ctrl-T] in the R interpreter.
1154
+
1155
+ INPUT:
1156
+
1157
+ - ``s`` -- string
1158
+
1159
+ OUTPUT: list of strings
1160
+
1161
+ EXAMPLES::
1162
+
1163
+ sage: dummy = r._tab_completion(use_disk_cache=False) # clean doctest
1164
+ sage: 'testInheritedMethods' in r.completions('tes')
1165
+ True
1166
+ """
1167
+ return [name for name in self._tab_completion() if name[:len(s)] == s]
1168
+
1169
+ def _commands(self):
1170
+ """
1171
+ Return list of all commands defined in R.
1172
+
1173
+ OUTPUT: list; a sorted list of strings
1174
+
1175
+ EXAMPLES::
1176
+
1177
+ sage: l = r._commands()
1178
+ sage: 'AIC' in l
1179
+ True
1180
+ sage: len(l) > 200
1181
+ True
1182
+ """
1183
+ v = RBaseCommands
1184
+
1185
+ ll = self('search()')._sage_() # loaded libs
1186
+
1187
+ for lib in ll:
1188
+ if lib in RFilteredPackages:
1189
+ continue
1190
+
1191
+ if lib.find("package:") != 0:
1192
+ continue # only packages
1193
+
1194
+ raw = self('objects("%s")' % lib)._sage_()
1195
+
1196
+ # TODO are there others? many of them are shortcuts or
1197
+ # should be done on another level, like selections in lists
1198
+ # instead of calling obj.[[( fun-args) or
1199
+ # other crazy stuff like that
1200
+
1201
+ # TODO further filtering, check if strings are now
1202
+ # really functions, in R: exists(s, mode = "function"))
1203
+ # (apply to vector with sapply(vec,func))
1204
+
1205
+ # filter only python compatible identifiers
1206
+ valid = re.compile('[^a-zA-Z0-9_]+')
1207
+ raw = [x for x in raw if valid.search(x) is None]
1208
+ v += raw
1209
+
1210
+ v.sort()
1211
+ return v
1212
+
1213
+ def _tab_completion(self, verbose=True, use_disk_cache=True):
1214
+ """
1215
+ Return list of all R functions.
1216
+
1217
+ INPUT:
1218
+
1219
+ - ``verbose`` -- boolean (default: ``True``); if ``True``, display
1220
+ debugging information
1221
+ - ``use_disk_cache`` -- boolean (default: ``True``); if ``True``, use
1222
+ the disk cache of tab completions to save time
1223
+
1224
+ OUTPUT: list of string
1225
+
1226
+ EXAMPLES::
1227
+
1228
+ sage: t = r._tab_completion(verbose=False)
1229
+ sage: len(t) > 200
1230
+ True
1231
+ """
1232
+ try:
1233
+ return self.__tab_completion
1234
+ except AttributeError:
1235
+ import sage.misc.persist
1236
+ if use_disk_cache:
1237
+ try:
1238
+ self.__tab_completion = sage.misc.persist.load(COMMANDS_CACHE)
1239
+ return self.__tab_completion
1240
+ except OSError:
1241
+ pass
1242
+ if verbose and use_disk_cache:
1243
+ print("\nBuilding R command completion list (this takes")
1244
+ print("a few seconds only the first time you do it).")
1245
+ print("To force rebuild later, delete %s." % COMMANDS_CACHE)
1246
+ v = self._commands()
1247
+ self.__tab_completion = v
1248
+ if len(v) > 200 and use_disk_cache:
1249
+ sage.misc.persist.save(v, COMMANDS_CACHE)
1250
+ return v
1251
+
1252
+ def plot(self, *args, **kwds):
1253
+ """
1254
+ The R plot function. Type r.help('plot') for much more extensive
1255
+ documentation about this function. See also below for a brief
1256
+ introduction to more plotting with R.
1257
+
1258
+ If one simply wants to view an R graphic, using this function is
1259
+ is sufficient (because it calls dev.off() to turn off the device).
1260
+
1261
+ However, if one wants to save the graphic to a specific file, it
1262
+ should be used as in the example below to write the output.
1263
+
1264
+ EXAMPLES:
1265
+
1266
+ This example saves a plot to the standard R output, usually a
1267
+ filename like ``Rplot001.png`` - from the command line, in the
1268
+ current directory, and in the cell directory in the
1269
+ notebook. We use a temporary directory in this example while
1270
+ doctesting this example, but you should use something
1271
+ persistent in your own code::
1272
+
1273
+ sage: from tempfile import TemporaryDirectory
1274
+ sage: with TemporaryDirectory() as d: # optional - rgraphics
1275
+ ....: _ = r.setwd(d)
1276
+ ....: r.plot("1:10")
1277
+ null device
1278
+ 1
1279
+
1280
+ To save to a specific file name, one should use :meth:`png` to set
1281
+ the output device to that file. If this is done in the notebook, it
1282
+ must be done in the same cell as the plot itself::
1283
+
1284
+ sage: filename = tmp_filename() + '.png'
1285
+ sage: r.png(filename='"%s"'%filename) # optional - rgraphics
1286
+ NULL
1287
+ sage: x = r([1,2,3])
1288
+ sage: y = r([4,5,6])
1289
+ sage: r.plot(x,y) # optional - rgraphics
1290
+ null device
1291
+ 1
1292
+ sage: import os; os.unlink(filename) # optional - rgraphics
1293
+
1294
+ Please note that for more extensive use of R's plotting
1295
+ capabilities (such as the lattices package), it is advisable
1296
+ to either use an interactive plotting device or to use the
1297
+ notebook. The following examples are not tested, because they
1298
+ differ depending on operating system::
1299
+
1300
+ sage: # not tested
1301
+ sage: r.X11()
1302
+ sage: r.quartz()
1303
+ sage: r.hist("rnorm(100)")
1304
+ sage: r.library("lattice")
1305
+ sage: r.histogram(x = '~ wt | cyl', data='mtcars')
1306
+ sage: r.dev_off()
1307
+
1308
+ In the notebook, one can use r.png() to open the device, but
1309
+ would need to use the following since R lattice graphics do
1310
+ not automatically print away from the command line::
1311
+
1312
+ sage: filename = tmp_filename() + '.png' # not needed in notebook, used for doctesting
1313
+ sage: r.png(filename='"%s"'%filename) # optional - rgraphics
1314
+ NULL
1315
+ sage: r.library("lattice")
1316
+ sage: r("print(histogram(~wt | cyl, data=mtcars))") # optional - rgraphics
1317
+ sage: import os; os.unlink(filename) # optional - rgraphics
1318
+ """
1319
+ # We have to define this to override the plot function defined in the
1320
+ # superclass.
1321
+ RFunction(self, 'plot')(*args, **kwds)
1322
+ return RFunction(self, 'dev.off')()
1323
+
1324
+ def eval(self, code, *args, **kwds):
1325
+ """
1326
+ Evaluates a command inside the R interpreter and returns the output
1327
+ as a string.
1328
+
1329
+ EXAMPLES::
1330
+
1331
+ sage: r.eval('1+1')
1332
+ '[1] 2'
1333
+ """
1334
+ self._lazy_init()
1335
+ return str(robjects.r(code)).rstrip()
1336
+
1337
+ def _r_to_sage_name(self, s):
1338
+ """
1339
+ Return a Sage/Python identifier from an R one. This involves
1340
+ replacing periods with underscores, <- with __, and prepending
1341
+ _ in front of Python keywords.
1342
+
1343
+ INPUT:
1344
+
1345
+ - ``s`` -- string
1346
+
1347
+ OUTPUT: string
1348
+
1349
+ EXAMPLES::
1350
+
1351
+ sage: f = r._r_to_sage_name
1352
+ sage: f('t.test')
1353
+ 't_test'
1354
+ sage: f('attr<-')
1355
+ 'attr__'
1356
+ sage: f('parent.env<-')
1357
+ 'parent_env__'
1358
+ sage: f('class')
1359
+ 'class_'
1360
+ """
1361
+ from keyword import iskeyword
1362
+ s = s.replace('.', '_')
1363
+ s = s.replace('<-', '__')
1364
+ if iskeyword(s):
1365
+ s += '_'
1366
+ return s
1367
+
1368
+ def _sage_to_r_name(self, s):
1369
+ r"""
1370
+ The reverse of :meth:`_r_to_sage_name`. See the docs for that method.
1371
+
1372
+ EXAMPLES::
1373
+
1374
+ sage: f = r._sage_to_r_name
1375
+ sage: f('t_test')
1376
+ 't.test'
1377
+ sage: f('attr__')
1378
+ 'attr<-'
1379
+ sage: f('parent_env__')
1380
+ 'parent.env<-'
1381
+ sage: r._r_to_sage_name(f('parent_env__'))
1382
+ 'parent_env__'
1383
+ sage: f('class_')
1384
+ 'class'
1385
+ """
1386
+ if len(s) > 1 and s[-2:] == "__":
1387
+ s = s[:-2] + '<-'
1388
+ if len(s) > 0 and s[-1] == '_':
1389
+ s = s[:-1]
1390
+ s = s.replace('_', '.')
1391
+ return s
1392
+
1393
+ def __getitem__(self, s):
1394
+ """
1395
+ Return the RFunction with name s.
1396
+
1397
+ INPUT:
1398
+
1399
+ - ``s`` -- string
1400
+
1401
+ OUTPUT: RFunction; the R function that in R has name s
1402
+
1403
+ EXAMPLES::
1404
+
1405
+ sage: r['as.data.frame']
1406
+ as.data.frame
1407
+ sage: r['print']
1408
+ print
1409
+ """
1410
+ return RFunction(self, s, r_name=True)
1411
+
1412
+ def chdir(self, dir):
1413
+ """
1414
+ Changes the working directory to ``dir``.
1415
+
1416
+ INPUT:
1417
+
1418
+ - ``dir`` -- the directory to change to
1419
+
1420
+ EXAMPLES::
1421
+
1422
+ sage: import tempfile
1423
+ sage: tmpdir = tempfile.mkdtemp()
1424
+ sage: r.chdir(tmpdir)
1425
+
1426
+ Check that ``tmpdir`` and ``r.getwd()`` refer to the same
1427
+ directory. We need to use ``realpath()`` in case ``$TMPDIR``
1428
+ (by default ``/tmp``) is a symbolic link (see :issue:`10264`).
1429
+
1430
+ ::
1431
+
1432
+ sage: os.path.realpath(tmpdir) == sageobj(r.getwd()) # known bug (issue #9970)
1433
+ True
1434
+ """
1435
+ self.execute('setwd(%r)' % dir)
1436
+
1437
+
1438
+ @instancedoc
1439
+ class RElement(ExtraTabCompletion, InterfaceElement):
1440
+
1441
+ def _tab_completion(self):
1442
+ """
1443
+ Return a list of all methods of this object.
1444
+
1445
+ .. NOTE::
1446
+
1447
+ Currently returns all R commands.
1448
+
1449
+ EXAMPLES::
1450
+
1451
+ sage: a = r([1,2,3])
1452
+ sage: t = a._tab_completion()
1453
+ sage: len(t) > 200
1454
+ True
1455
+ """
1456
+ # TODO: rewrite it, just take methods(class=class(self))
1457
+ return self.parent()._tab_completion()
1458
+
1459
+ def tilde(self, x):
1460
+ """
1461
+ The tilde regression operator in R.
1462
+
1463
+ EXAMPLES::
1464
+
1465
+ sage: x = r([1,2,3,4,5])
1466
+ sage: y = r([3,5,7,9,11])
1467
+ sage: a = r.lm( y.tilde(x) ) # lm( y ~ x )
1468
+ sage: d = a._sage_()
1469
+ sage: d['DATA']['coefficients']['DATA'][1]
1470
+ 2
1471
+ """
1472
+ par = self.parent()
1473
+ rx = par(x)
1474
+ return par.new("%s ~ %s" % (self.name(), rx.name()))
1475
+
1476
+ stat_model = tilde
1477
+
1478
+ def is_string(self):
1479
+ """
1480
+ Tell whether this element is a string.
1481
+
1482
+ EXAMPLES::
1483
+
1484
+ sage: r('"abc"').is_string()
1485
+ True
1486
+ sage: r([1,2,3]).is_string()
1487
+ False
1488
+ """
1489
+ return isinstance(self.sage(), str)
1490
+
1491
+ def __len__(self):
1492
+ """
1493
+ Return the length of this object.
1494
+
1495
+ OUTPUT: integer
1496
+
1497
+ EXAMPLES::
1498
+
1499
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1500
+ sage: len(x)
1501
+ 5
1502
+ """
1503
+ return self.parent()('length(%s)' % self.name()).sage()
1504
+
1505
+ def __getattr__(self, attrname):
1506
+ """
1507
+ Return attribute of this object, which is an R function with this object
1508
+ as the first input.
1509
+
1510
+ INPUT:
1511
+
1512
+ - ``attrname`` -- string
1513
+
1514
+ OUTPUT: RFunctionElement
1515
+
1516
+ EXAMPLES::
1517
+
1518
+ sage: x = r([1,2,3])
1519
+ sage: length = x.length
1520
+ sage: type(length)
1521
+ <class 'sage.interfaces.r.RFunctionElement'>
1522
+ sage: length()
1523
+ [1] 3
1524
+ """
1525
+ try:
1526
+ # First try to get a regular python attribute. This makes it
1527
+ # possible to still use attributes like _r_to_sage_converter
1528
+ # internally.
1529
+ self.__getattribute__(attrname)
1530
+ except AttributeError:
1531
+ self._check_valid()
1532
+ if attrname[:1] == "_":
1533
+ raise AttributeError("Attribute {} is not allowed to start with an underscore.".format(attrname))
1534
+ return RFunctionElement(self, attrname)
1535
+
1536
+ def __getitem__(self, n):
1537
+ """
1538
+ Return element(s) of ``self``.
1539
+
1540
+ INPUT:
1541
+
1542
+ - ``n`` -- integer, a tuple, a string that makes sense to R, or an
1543
+ RElement
1544
+
1545
+ OUTPUT: RElement
1546
+
1547
+ EXAMPLES::
1548
+
1549
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1550
+ sage: x[0]
1551
+ numeric(0)
1552
+ sage: x[1]
1553
+ [1] 10.4
1554
+ sage: x[-1]
1555
+ [1] 5.6 3.1 6.4 21.7
1556
+ sage: x[-2]
1557
+ [1] 10.4 3.1 6.4 21.7
1558
+ sage: x[-3]
1559
+ [1] 10.4 5.6 6.4 21.7
1560
+ sage: x['c(2,3)']
1561
+ [1] 5.6 3.1
1562
+ sage: key = r.c(2,3)
1563
+ sage: x[key]
1564
+ [1] 5.6 3.1
1565
+ sage: m = r.array('1:3',r.c(2,4,2))
1566
+ sage: m
1567
+ , , 1
1568
+ [,1] [,2] [,3] [,4]
1569
+ [1,] 1 3 2 1
1570
+ [2,] 2 1 3 2
1571
+ , , 2
1572
+ [,1] [,2] [,3] [,4]
1573
+ [1,] 3 2 1 3
1574
+ [2,] 1 3 2 1
1575
+ sage: m[1,2,2]
1576
+ [1] 2
1577
+ sage: m[1,r.c(1,2),1]
1578
+ [1] 1 3
1579
+ """
1580
+ P = self._check_valid()
1581
+ if isinstance(n, str):
1582
+ n = n.replace('self', self._name)
1583
+ return P.new('%s[%s]' % (self._name, n))
1584
+ elif parent(n) is P: # the key is RElement itself
1585
+ return P.new('%s[%s]' % (self._name, n.name()))
1586
+ elif not isinstance(n, tuple):
1587
+ return P.new('%s[%s]' % (self._name, n))
1588
+ else:
1589
+ L = []
1590
+ for i in range(len(n)):
1591
+ if parent(n[i]) is P:
1592
+ L.append(n[i].name())
1593
+ else:
1594
+ L.append(str(n[i]))
1595
+ return P.new('%s[%s]' % (self._name, ','.join(L)))
1596
+
1597
+ def __bool__(self):
1598
+ """
1599
+ Implement ``bool(self)``.
1600
+
1601
+ .. NOTE::
1602
+
1603
+ bool(self) will only return ``True`` if ``self == 0`` contains a
1604
+ FALSE in its representation.
1605
+
1606
+ EXAMPLES::
1607
+
1608
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1609
+ sage: bool(x)
1610
+ True
1611
+ sage: y = r([0,0,0,0])
1612
+ sage: bool(y)
1613
+ False
1614
+ sage: bool(r(0))
1615
+ False
1616
+ sage: bool(r(1))
1617
+ True
1618
+ """
1619
+ return "FALSE" in repr(self == 0)
1620
+
1621
+ def _comparison(self, other, symbol):
1622
+ """
1623
+ Used to implement comparison of two objects.
1624
+
1625
+ INPUT:
1626
+
1627
+ - ``other`` -- RElement
1628
+ - ``symbol`` -- string
1629
+
1630
+ OUTPUT: RElement; output is an R element (not a bool!)
1631
+
1632
+ TESTS::
1633
+
1634
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1635
+ sage: x._comparison(10.4, "==")
1636
+ [1] TRUE FALSE FALSE FALSE FALSE
1637
+ """
1638
+ P = self.parent()
1639
+ other = P(other)
1640
+ return P('%s %s %s' % (self.name(), symbol, other.name()))
1641
+
1642
+ def __eq__(self, other):
1643
+ """
1644
+ Equality testing term by term.
1645
+
1646
+ INPUT:
1647
+
1648
+ - ``other`` -- RElement
1649
+
1650
+ OUTPUT: RElement; an R element (not a bool!)
1651
+
1652
+ EXAMPLES:
1653
+
1654
+ Notice that comparison is term by term and returns an R element. ::
1655
+
1656
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1657
+ sage: x == 10.4
1658
+ [1] TRUE FALSE FALSE FALSE FALSE
1659
+ """
1660
+ return self._comparison(other, "==")
1661
+
1662
+ def __lt__(self, other):
1663
+ """
1664
+ Less than testing term by term.
1665
+
1666
+ INPUT:
1667
+
1668
+ - ``other`` -- RElement
1669
+
1670
+ OUTPUT: RElement; an R element (not a bool!)
1671
+
1672
+ EXAMPLES:
1673
+
1674
+ Notice that comparison is term by term and returns an R element. ::
1675
+
1676
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1677
+ sage: x < 7
1678
+ [1] FALSE TRUE TRUE TRUE FALSE
1679
+ """
1680
+ return self._comparison(other, "<")
1681
+
1682
+ def __gt__(self, other):
1683
+ """
1684
+ Greater than testing term by term.
1685
+
1686
+ INPUT:
1687
+
1688
+ - ``other`` -- RElement
1689
+
1690
+ OUTPUT: RElement; an R element (not a bool!)
1691
+
1692
+ EXAMPLES:
1693
+
1694
+ Notice that comparison is term by term and returns an R element. ::
1695
+
1696
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1697
+ sage: x > 8
1698
+ [1] TRUE FALSE FALSE FALSE TRUE
1699
+ """
1700
+ return self._comparison(other, ">")
1701
+
1702
+ def __le__(self, other):
1703
+ """
1704
+ Less than or equal testing term by term.
1705
+
1706
+ INPUT:
1707
+
1708
+ - ``other`` -- RElement
1709
+
1710
+ OUTPUT: RElement; an R element (not a bool!)
1711
+
1712
+ EXAMPLES::
1713
+
1714
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1715
+ sage: x <= 10.4
1716
+ [1] TRUE TRUE TRUE TRUE FALSE
1717
+ """
1718
+ return self._comparison(other, "<=")
1719
+
1720
+ def __ge__(self, other):
1721
+ """
1722
+ Greater than or equal testing term by term.
1723
+
1724
+ INPUT:
1725
+
1726
+ - ``other`` -- RElement
1727
+
1728
+ OUTPUT: RElement; an R element (not a bool!)
1729
+
1730
+ EXAMPLES::
1731
+
1732
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1733
+ sage: x >= 10.4
1734
+ [1] TRUE FALSE FALSE FALSE TRUE
1735
+ """
1736
+ return self._comparison(other, ">=")
1737
+
1738
+ def __ne__(self, other):
1739
+ """
1740
+ Not equal testing term by term.
1741
+
1742
+ INPUT:
1743
+
1744
+ - ``other`` -- RElement
1745
+
1746
+ OUTPUT: RElement; an R element (not a bool!)
1747
+
1748
+ EXAMPLES::
1749
+
1750
+ sage: x = r([10.4,5.6,3.1,6.4,21.7])
1751
+ sage: x != 10.4
1752
+ [1] FALSE TRUE TRUE TRUE TRUE
1753
+ """
1754
+ return self._comparison(other, "!=")
1755
+
1756
+ def dot_product(self, other):
1757
+ """
1758
+ Implement the notation ``self . other``.
1759
+
1760
+ INPUT:
1761
+
1762
+ - ``self``, ``other`` -- R elements
1763
+
1764
+ OUTPUT: R element
1765
+
1766
+ EXAMPLES::
1767
+
1768
+ sage: c = r.c(1,2,3,4)
1769
+ sage: c.dot_product(c.t())
1770
+ [,1] [,2] [,3] [,4]
1771
+ [1,] 1 2 3 4
1772
+ [2,] 2 4 6 8
1773
+ [3,] 3 6 9 12
1774
+ [4,] 4 8 12 16
1775
+
1776
+ sage: v = r([3,-1,8])
1777
+ sage: v.dot_product(v)
1778
+ [,1]
1779
+ [1,] 74
1780
+ """
1781
+ P = self._check_valid()
1782
+ Q = P(other)
1783
+ # the R operator is %*% for matrix multiplication
1784
+ return P('%s %%*%% %s' % (self.name(), Q.name()))
1785
+
1786
+ def _sage_(self):
1787
+ r"""
1788
+ Return Sage representation of the R object.
1789
+
1790
+ R objects are basic C structures, of different kind, that can
1791
+ be stacked together. This is similar to Python lists with
1792
+ variable objects, including lists of lists. If R lists have
1793
+ names, they are translated to a Python dictionary, with anonymous
1794
+ list entries called ``#{number}``.
1795
+
1796
+ OUTPUT: object; Python object
1797
+
1798
+ EXAMPLES::
1799
+
1800
+ sage: rs = r.summary(r.c(1,4,3,4,3,2,5,1))
1801
+ sage: d = rs._sage_()
1802
+ sage: sorted(d.items())
1803
+ [('DATA', [1, 1.75, 3, 2.875, 4, 5]),
1804
+ ('_Names', ['Min.', '1st Qu.', 'Median', 'Mean', '3rd Qu.', 'Max.']),
1805
+ ('_r_class', ['summaryDefault', 'table'])]
1806
+ """
1807
+ self._check_valid()
1808
+ P = self.parent()
1809
+
1810
+ with localconverter(P._r_to_sage_converter) as cv:
1811
+ return robjects.r(self.name())
1812
+
1813
+ def _latex_(self):
1814
+ r"""
1815
+ Return LaTeX representation of this R object.
1816
+
1817
+ This calls the ``latex`` command in R.
1818
+
1819
+ OUTPUT: a latex expression (basically a string)
1820
+
1821
+ EXAMPLES::
1822
+
1823
+ sage: latex(r(2)) # optional - Hmisc (R package)
1824
+ 2
1825
+ """
1826
+ from sage.misc.latex import LatexExpr
1827
+ self._check_valid()
1828
+ P = self.parent()
1829
+ # latex is in Hmisc, this is currently not part of Sage's R!!!
1830
+ try:
1831
+ P.library('Hmisc')
1832
+ except ImportError:
1833
+ raise RuntimeError("The R package 'Hmisc' is required for R to LaTeX conversion, but it is not available.")
1834
+ return LatexExpr(P.eval('latex(%s, file="");' % self.name()))
1835
+
1836
+
1837
+ @instancedoc
1838
+ class RFunctionElement(InterfaceFunctionElement):
1839
+ def __reduce__(self):
1840
+ """
1841
+ EXAMPLES::
1842
+
1843
+ sage: a = r([1,2,3])
1844
+ sage: a.mean
1845
+ mean
1846
+ sage: dumps(a.mean)
1847
+ Traceback (most recent call last):
1848
+ ...
1849
+ NotImplementedError: pickling of R element methods is not yet supported
1850
+ """
1851
+ raise NotImplementedError("pickling of R element methods is not yet supported")
1852
+
1853
+ def _instancedoc_(self):
1854
+ """
1855
+ Return the help for ``self`` as a string.
1856
+
1857
+ EXAMPLES::
1858
+
1859
+ sage: a = r([1,2,3])
1860
+ sage: length = a.length
1861
+ sage: print(length.__doc__)
1862
+ title
1863
+ -----
1864
+ <BLANKLINE>
1865
+ Length of an Object
1866
+ <BLANKLINE>
1867
+ name
1868
+ ----
1869
+ <BLANKLINE>
1870
+ length
1871
+ ...
1872
+ """
1873
+ M = self._obj.parent()
1874
+ return M.help(self._name)
1875
+
1876
+ def _sage_src_(self):
1877
+ """
1878
+ Return the source code of ``self``.
1879
+
1880
+ EXAMPLES::
1881
+
1882
+ sage: a = r([1,2,3])
1883
+ sage: length = a.length
1884
+ sage: print(length._sage_src_())
1885
+ function (x) .Primitive("length")
1886
+ """
1887
+ M = self._obj.parent()
1888
+ return M.source(self._name)
1889
+
1890
+ def __call__(self, *args, **kwds):
1891
+ """
1892
+ EXAMPLES::
1893
+
1894
+ sage: a = r([1,2,3])
1895
+ sage: length = a.length
1896
+ sage: length()
1897
+ [1] 3
1898
+ """
1899
+ return self._obj.parent().function_call(self._name, args=[self._obj] + list(args), kwds=kwds)
1900
+
1901
+
1902
+ @instancedoc
1903
+ class RFunction(InterfaceFunction):
1904
+ def __init__(self, parent, name, r_name=None):
1905
+ """
1906
+ A Function in the R interface.
1907
+
1908
+ INPUT:
1909
+
1910
+ - ``parent`` -- the R interface
1911
+ - ``name`` -- the name of the function for Python
1912
+ - ``r_name`` -- the name of the function in R itself (which can have dots in it)
1913
+
1914
+ EXAMPLES::
1915
+
1916
+ sage: length = r.length
1917
+ sage: type(length)
1918
+ <class 'sage.interfaces.r.RFunction'>
1919
+ sage: loads(dumps(length))
1920
+ length
1921
+ """
1922
+ self._parent = parent
1923
+ if r_name:
1924
+ self._name = name
1925
+ else:
1926
+ self._name = parent._sage_to_r_name(name)
1927
+
1928
+ def __eq__(self, other):
1929
+ """
1930
+ EXAMPLES::
1931
+
1932
+ sage: r.mean == loads(dumps(r.mean))
1933
+ True
1934
+ sage: r.mean == r.lr
1935
+ False
1936
+ """
1937
+ return (isinstance(other, RFunction) and
1938
+ self._name == other._name)
1939
+
1940
+ def __ne__(self, other):
1941
+ """
1942
+ EXAMPLES::
1943
+
1944
+ sage: r.mean != loads(dumps(r.mean))
1945
+ False
1946
+ sage: r.mean != r.lr
1947
+ True
1948
+ """
1949
+ return not (self == other)
1950
+
1951
+ def _instancedoc_(self):
1952
+ """
1953
+ Return the help for ``self``.
1954
+
1955
+ EXAMPLES::
1956
+
1957
+ sage: length = r.length
1958
+ sage: print(length.__doc__)
1959
+ title
1960
+ -----
1961
+ <BLANKLINE>
1962
+ Length of an Object
1963
+ <BLANKLINE>
1964
+ name
1965
+ ----
1966
+ <BLANKLINE>
1967
+ length
1968
+ ...
1969
+ """
1970
+ M = self._parent
1971
+ return M.help(self._name)
1972
+
1973
+ def _sage_src_(self):
1974
+ """
1975
+ Return the source of ``self``.
1976
+
1977
+ EXAMPLES::
1978
+
1979
+ sage: length = r.length
1980
+ sage: print(length._sage_src_())
1981
+ function (x) .Primitive("length")
1982
+ """
1983
+ M = self._parent
1984
+ return M.source(self._name)
1985
+
1986
+ def __call__(self, *args, **kwds):
1987
+ """
1988
+ EXAMPLES::
1989
+
1990
+ sage: length = r.length
1991
+ sage: length([1,2,3])
1992
+ [1] 3
1993
+ """
1994
+ return self._parent.function_call(self._name, args=list(args), kwds=kwds)
1995
+
1996
+
1997
+ def is_RElement(x):
1998
+ """
1999
+ Return ``True`` if x is an element in an R interface.
2000
+
2001
+ INPUT:
2002
+
2003
+ - ``x`` -- object
2004
+
2005
+ OUTPUT: boolean
2006
+
2007
+ EXAMPLES::
2008
+
2009
+ sage: from sage.interfaces.r import is_RElement
2010
+ sage: is_RElement(2)
2011
+ doctest:...: DeprecationWarning: the function is_RElement is deprecated; use isinstance(x, sage.interfaces.abc.RElement) instead
2012
+ See https://github.com/sagemath/sage/issues/34804 for details.
2013
+ False
2014
+ sage: is_RElement(r(2))
2015
+ True
2016
+ """
2017
+ from sage.misc.superseded import deprecation
2018
+ deprecation(34804, "the function is_RElement is deprecated; use isinstance(x, sage.interfaces.abc.RElement) instead")
2019
+
2020
+ return isinstance(x, RElement)
2021
+
2022
+
2023
+ # An instance of R
2024
+ r = R()
2025
+
2026
+
2027
+ def reduce_load_R():
2028
+ """
2029
+ Used for reconstructing a copy of the R interpreter from a pickle.
2030
+
2031
+ EXAMPLES::
2032
+
2033
+ sage: from sage.interfaces.r import reduce_load_R
2034
+ sage: reduce_load_R()
2035
+ R Interpreter
2036
+ """
2037
+ return r
2038
+
2039
+
2040
+ def r_console():
2041
+ """
2042
+ Spawn a new R command-line session.
2043
+
2044
+ EXAMPLES::
2045
+
2046
+ sage: r.console() # not tested
2047
+ R version 2.6.1 (2007-11-26)
2048
+ Copyright (C) 2007 The R Foundation for Statistical Computing
2049
+ ISBN 3-900051-07-0
2050
+ ...
2051
+ """
2052
+ from sage.repl.rich_output.display_manager import get_display_manager
2053
+ if not get_display_manager().is_in_terminal():
2054
+ raise RuntimeError('Can use the console only in the terminal. Try %%r magics instead.')
2055
+ # This will only spawn local processes
2056
+ os.system('R --vanilla')
2057
+
2058
+
2059
+ def r_version():
2060
+ """
2061
+ Return the R version.
2062
+
2063
+ EXAMPLES::
2064
+
2065
+ sage: r_version() # not tested
2066
+ ((3, 0, 1), 'R version 3.0.1 (2013-05-16)')
2067
+ sage: rint, rstr = r_version()
2068
+ sage: rint[0] >= 3
2069
+ True
2070
+ sage: rstr.startswith('R version')
2071
+ True
2072
+ """
2073
+ return r.version()
2074
+
2075
+
2076
+ class HelpExpression(str):
2077
+ """
2078
+ Used to improve printing of output of r.help.
2079
+ """
2080
+ def __repr__(self):
2081
+ r"""
2082
+ Return string representation of ``self``.
2083
+
2084
+ OUTPUT: string
2085
+
2086
+ EXAMPLES::
2087
+
2088
+ sage: a = sage.interfaces.r.HelpExpression("This\nis\nR!")
2089
+ sage: type(a)
2090
+ <class 'sage.interfaces.r.HelpExpression'>
2091
+ sage: a
2092
+ This
2093
+ is
2094
+ R!
2095
+ """
2096
+ return str(self)