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