##// END OF EJS Templates
Load rpy2.ipython for rmagic, print deprecation warning
Thomas Kluyver -
Show More
@@ -1,696 +1,706 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 ======
4 4 Rmagic
5 5 ======
6 6
7 7 Magic command interface for interactive work with R via rpy2
8 8
9 9 .. note::
10 10
11 11 The ``rpy2`` package needs to be installed separately. It
12 12 can be obtained using ``easy_install`` or ``pip``.
13 13
14 14 You will also need a working copy of R.
15 15
16 16 Usage
17 17 =====
18 18
19 19 To enable the magics below, execute ``%load_ext rmagic``.
20 20
21 21 ``%R``
22 22
23 23 {R_DOC}
24 24
25 25 ``%Rpush``
26 26
27 27 {RPUSH_DOC}
28 28
29 29 ``%Rpull``
30 30
31 31 {RPULL_DOC}
32 32
33 33 ``%Rget``
34 34
35 35 {RGET_DOC}
36 36
37 37 """
38 38 from __future__ import print_function
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Copyright (C) 2012 The IPython Development Team
42 42 #
43 43 # Distributed under the terms of the BSD License. The full license is in
44 44 # the file COPYING, distributed as part of this software.
45 45 #-----------------------------------------------------------------------------
46 46
47 47 import sys
48 48 import tempfile
49 49 from glob import glob
50 50 from shutil import rmtree
51 import warnings
51 52
52 53 # numpy and rpy2 imports
53 54
54 55 import numpy as np
55 56
56 57 import rpy2.rinterface as ri
57 58 import rpy2.robjects as ro
58 59 try:
59 60 from rpy2.robjects import pandas2ri
60 61 pandas2ri.activate()
61 62 except ImportError:
62 63 pandas2ri = None
63 64 from rpy2.robjects import numpy2ri
64 65 numpy2ri.activate()
65 66
66 67 # IPython imports
67 68
68 69 from IPython.core.displaypub import publish_display_data
69 70 from IPython.core.magic import (Magics, magics_class, line_magic,
70 71 line_cell_magic, needs_local_scope)
71 72 from IPython.testing.skipdoctest import skip_doctest
72 73 from IPython.core.magic_arguments import (
73 74 argument, magic_arguments, parse_argstring
74 75 )
75 76 from IPython.external.simplegeneric import generic
76 77 from IPython.utils.py3compat import (str_to_unicode, unicode_to_str, PY3,
77 78 unicode_type)
78 79 from IPython.utils.text import dedent
79 80
80 81 class RInterpreterError(ri.RRuntimeError):
81 82 """An error when running R code in a %%R magic cell."""
82 83 def __init__(self, line, err, stdout):
83 84 self.line = line
84 85 self.err = err.rstrip()
85 86 self.stdout = stdout.rstrip()
86 87
87 88 def __unicode__(self):
88 89 s = 'Failed to parse and evaluate line %r.\nR error message: %r' % \
89 90 (self.line, self.err)
90 91 if self.stdout and (self.stdout != self.err):
91 92 s += '\nR stdout:\n' + self.stdout
92 93 return s
93 94
94 95 if PY3:
95 96 __str__ = __unicode__
96 97 else:
97 98 def __str__(self):
98 99 return unicode_to_str(unicode(self), 'utf-8')
99 100
100 101 def Rconverter(Robj, dataframe=False):
101 102 """
102 103 Convert an object in R's namespace to one suitable
103 104 for ipython's namespace.
104 105
105 106 For a data.frame, it tries to return a structured array.
106 107 It first checks for colnames, then names.
107 108 If all are NULL, it returns np.asarray(Robj), else
108 109 it tries to construct a recarray
109 110
110 111 Parameters
111 112 ----------
112 113
113 114 Robj: an R object returned from rpy2
114 115 """
115 116 is_data_frame = ro.r('is.data.frame')
116 117 colnames = ro.r('colnames')
117 118 rownames = ro.r('rownames') # with pandas, these could be used for the index
118 119 names = ro.r('names')
119 120
120 121 if dataframe:
121 122 as_data_frame = ro.r('as.data.frame')
122 123 cols = colnames(Robj)
123 124 _names = names(Robj)
124 125 if cols != ri.NULL:
125 126 Robj = as_data_frame(Robj)
126 127 names = tuple(np.array(cols))
127 128 elif _names != ri.NULL:
128 129 names = tuple(np.array(_names))
129 130 else: # failed to find names
130 131 return np.asarray(Robj)
131 132 Robj = np.rec.fromarrays(Robj, names = names)
132 133 return np.asarray(Robj)
133 134
134 135 @generic
135 136 def pyconverter(pyobj):
136 137 """Convert Python objects to R objects. Add types using the decorator:
137 138
138 139 @pyconverter.when_type
139 140 """
140 141 return pyobj
141 142
142 143 # The default conversion for lists seems to make them a nested list. That has
143 144 # some advantages, but is rarely convenient, so for interactive use, we convert
144 145 # lists to a numpy array, which becomes an R vector.
145 146 @pyconverter.when_type(list)
146 147 def pyconverter_list(pyobj):
147 148 return np.asarray(pyobj)
148 149
149 150 if pandas2ri is None:
150 151 # pandas2ri was new in rpy2 2.3.3, so for now we'll fallback to pandas'
151 152 # conversion function.
152 153 try:
153 154 from pandas import DataFrame
154 155 from pandas.rpy.common import convert_to_r_dataframe
155 156 @pyconverter.when_type(DataFrame)
156 157 def pyconverter_dataframe(pyobj):
157 158 return convert_to_r_dataframe(pyobj, strings_as_factors=True)
158 159 except ImportError:
159 160 pass
160 161
161 162 @magics_class
162 163 class RMagics(Magics):
163 164 """A set of magics useful for interactive work with R via rpy2.
164 165 """
165 166
166 167 def __init__(self, shell, Rconverter=Rconverter,
167 168 pyconverter=pyconverter,
168 169 cache_display_data=False):
169 170 """
170 171 Parameters
171 172 ----------
172 173
173 174 shell : IPython shell
174 175
175 176 Rconverter : callable
176 177 To be called on values taken from R before putting them in the
177 178 IPython namespace.
178 179
179 180 pyconverter : callable
180 181 To be called on values in ipython namespace before
181 182 assigning to variables in rpy2.
182 183
183 184 cache_display_data : bool
184 185 If True, the published results of the final call to R are
185 186 cached in the variable 'display_cache'.
186 187
187 188 """
188 189 super(RMagics, self).__init__(shell)
189 190 self.cache_display_data = cache_display_data
190 191
191 192 self.r = ro.R()
192 193
193 194 self.Rstdout_cache = []
194 195 self.pyconverter = pyconverter
195 196 self.Rconverter = Rconverter
196 197
197 198 def eval(self, line):
198 199 '''
199 200 Parse and evaluate a line of R code with rpy2.
200 201 Returns the output to R's stdout() connection,
201 202 the value generated by evaluating the code, and a
202 203 boolean indicating whether the return value would be
203 204 visible if the line of code were evaluated in an R REPL.
204 205
205 206 R Code evaluation and visibility determination are
206 207 done via an R call of the form withVisible({<code>})
207 208
208 209 '''
209 210 old_writeconsole = ri.get_writeconsole()
210 211 ri.set_writeconsole(self.write_console)
211 212 try:
212 213 res = ro.r("withVisible({%s\n})" % line)
213 214 value = res[0] #value (R object)
214 215 visible = ro.conversion.ri2py(res[1])[0] #visible (boolean)
215 216 except (ri.RRuntimeError, ValueError) as exception:
216 217 warning_or_other_msg = self.flush() # otherwise next return seems to have copy of error
217 218 raise RInterpreterError(line, str_to_unicode(str(exception)), warning_or_other_msg)
218 219 text_output = self.flush()
219 220 ri.set_writeconsole(old_writeconsole)
220 221 return text_output, value, visible
221 222
222 223 def write_console(self, output):
223 224 '''
224 225 A hook to capture R's stdout in a cache.
225 226 '''
226 227 self.Rstdout_cache.append(output)
227 228
228 229 def flush(self):
229 230 '''
230 231 Flush R's stdout cache to a string, returning the string.
231 232 '''
232 233 value = ''.join([str_to_unicode(s, 'utf-8') for s in self.Rstdout_cache])
233 234 self.Rstdout_cache = []
234 235 return value
235 236
236 237 @skip_doctest
237 238 @needs_local_scope
238 239 @line_magic
239 240 def Rpush(self, line, local_ns=None):
240 241 '''
241 242 A line-level magic for R that pushes
242 243 variables from python to rpy2. The line should be made up
243 244 of whitespace separated variable names in the IPython
244 245 namespace::
245 246
246 247 In [7]: import numpy as np
247 248
248 249 In [8]: X = np.array([4.5,6.3,7.9])
249 250
250 251 In [9]: X.mean()
251 252 Out[9]: 6.2333333333333343
252 253
253 254 In [10]: %Rpush X
254 255
255 256 In [11]: %R mean(X)
256 257 Out[11]: array([ 6.23333333])
257 258
258 259 '''
259 260 if local_ns is None:
260 261 local_ns = {}
261 262
262 263 inputs = line.split(' ')
263 264 for input in inputs:
264 265 try:
265 266 val = local_ns[input]
266 267 except KeyError:
267 268 try:
268 269 val = self.shell.user_ns[input]
269 270 except KeyError:
270 271 # reraise the KeyError as a NameError so that it looks like
271 272 # the standard python behavior when you use an unnamed
272 273 # variable
273 274 raise NameError("name '%s' is not defined" % input)
274 275
275 276 self.r.assign(input, self.pyconverter(val))
276 277
277 278 @skip_doctest
278 279 @magic_arguments()
279 280 @argument(
280 281 '-d', '--as_dataframe', action='store_true',
281 282 default=False,
282 283 help='Convert objects to data.frames before returning to ipython.'
283 284 )
284 285 @argument(
285 286 'outputs',
286 287 nargs='*',
287 288 )
288 289 @line_magic
289 290 def Rpull(self, line):
290 291 '''
291 292 A line-level magic for R that pulls
292 293 variables from python to rpy2::
293 294
294 295 In [18]: _ = %R x = c(3,4,6.7); y = c(4,6,7); z = c('a',3,4)
295 296
296 297 In [19]: %Rpull x y z
297 298
298 299 In [20]: x
299 300 Out[20]: array([ 3. , 4. , 6.7])
300 301
301 302 In [21]: y
302 303 Out[21]: array([ 4., 6., 7.])
303 304
304 305 In [22]: z
305 306 Out[22]:
306 307 array(['a', '3', '4'],
307 308 dtype='|S1')
308 309
309 310
310 311 If --as_dataframe, then each object is returned as a structured array
311 312 after first passed through "as.data.frame" in R before
312 313 being calling self.Rconverter.
313 314 This is useful when a structured array is desired as output, or
314 315 when the object in R has mixed data types.
315 316 See the %%R docstring for more examples.
316 317
317 318 Notes
318 319 -----
319 320
320 321 Beware that R names can have '.' so this is not fool proof.
321 322 To avoid this, don't name your R objects with '.'s...
322 323
323 324 '''
324 325 args = parse_argstring(self.Rpull, line)
325 326 outputs = args.outputs
326 327 for output in outputs:
327 328 self.shell.push({output:self.Rconverter(self.r(output),dataframe=args.as_dataframe)})
328 329
329 330 @skip_doctest
330 331 @magic_arguments()
331 332 @argument(
332 333 '-d', '--as_dataframe', action='store_true',
333 334 default=False,
334 335 help='Convert objects to data.frames before returning to ipython.'
335 336 )
336 337 @argument(
337 338 'output',
338 339 nargs=1,
339 340 type=str,
340 341 )
341 342 @line_magic
342 343 def Rget(self, line):
343 344 '''
344 345 Return an object from rpy2, possibly as a structured array (if possible).
345 346 Similar to Rpull except only one argument is accepted and the value is
346 347 returned rather than pushed to self.shell.user_ns::
347 348
348 349 In [3]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
349 350
350 351 In [4]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
351 352
352 353 In [5]: %R -i datapy
353 354
354 355 In [6]: %Rget datapy
355 356 Out[6]:
356 357 array([['1', '2', '3', '4'],
357 358 ['2', '3', '2', '5'],
358 359 ['a', 'b', 'c', 'e']],
359 360 dtype='|S1')
360 361
361 362 In [7]: %Rget -d datapy
362 363 Out[7]:
363 364 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
364 365 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
365 366
366 367 '''
367 368 args = parse_argstring(self.Rget, line)
368 369 output = args.output
369 370 return self.Rconverter(self.r(output[0]),dataframe=args.as_dataframe)
370 371
371 372
372 373 @skip_doctest
373 374 @magic_arguments()
374 375 @argument(
375 376 '-i', '--input', action='append',
376 377 help='Names of input variable from shell.user_ns to be assigned to R variables of the same names after calling self.pyconverter. Multiple names can be passed separated only by commas with no whitespace.'
377 378 )
378 379 @argument(
379 380 '-o', '--output', action='append',
380 381 help='Names of variables to be pushed from rpy2 to shell.user_ns after executing cell body and applying self.Rconverter. Multiple names can be passed separated only by commas with no whitespace.'
381 382 )
382 383 @argument(
383 384 '-w', '--width', type=int,
384 385 help='Width of png plotting device sent as an argument to *png* in R.'
385 386 )
386 387 @argument(
387 388 '-h', '--height', type=int,
388 389 help='Height of png plotting device sent as an argument to *png* in R.'
389 390 )
390 391
391 392 @argument(
392 393 '-d', '--dataframe', action='append',
393 394 help='Convert these objects to data.frames and return as structured arrays.'
394 395 )
395 396 @argument(
396 397 '-u', '--units', type=unicode_type, choices=["px", "in", "cm", "mm"],
397 398 help='Units of png plotting device sent as an argument to *png* in R. One of ["px", "in", "cm", "mm"].'
398 399 )
399 400 @argument(
400 401 '-r', '--res', type=int,
401 402 help='Resolution of png plotting device sent as an argument to *png* in R. Defaults to 72 if *units* is one of ["in", "cm", "mm"].'
402 403 )
403 404 @argument(
404 405 '-p', '--pointsize', type=int,
405 406 help='Pointsize of png plotting device sent as an argument to *png* in R.'
406 407 )
407 408 @argument(
408 409 '-b', '--bg',
409 410 help='Background of png plotting device sent as an argument to *png* in R.'
410 411 )
411 412 @argument(
412 413 '-n', '--noreturn',
413 414 help='Force the magic to not return anything.',
414 415 action='store_true',
415 416 default=False
416 417 )
417 418 @argument(
418 419 'code',
419 420 nargs='*',
420 421 )
421 422 @needs_local_scope
422 423 @line_cell_magic
423 424 def R(self, line, cell=None, local_ns=None):
424 425 '''
425 426 Execute code in R, and pull some of the results back into the Python namespace.
426 427
427 428 In line mode, this will evaluate an expression and convert the returned value to a Python object.
428 429 The return value is determined by rpy2's behaviour of returning the result of evaluating the
429 430 final line.
430 431
431 432 Multiple R lines can be executed by joining them with semicolons::
432 433
433 434 In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
434 435 Out[9]: array([ 4.25])
435 436
436 437 In cell mode, this will run a block of R code. The resulting value
437 438 is printed if it would printed be when evaluating the same code
438 439 within a standard R REPL.
439 440
440 441 Nothing is returned to python by default in cell mode::
441 442
442 443 In [10]: %%R
443 444 ....: Y = c(2,4,3,9)
444 445 ....: summary(lm(Y~X))
445 446
446 447 Call:
447 448 lm(formula = Y ~ X)
448 449
449 450 Residuals:
450 451 1 2 3 4
451 452 0.88 -0.24 -2.28 1.64
452 453
453 454 Coefficients:
454 455 Estimate Std. Error t value Pr(>|t|)
455 456 (Intercept) 0.0800 2.3000 0.035 0.975
456 457 X 1.0400 0.4822 2.157 0.164
457 458
458 459 Residual standard error: 2.088 on 2 degrees of freedom
459 460 Multiple R-squared: 0.6993,Adjusted R-squared: 0.549
460 461 F-statistic: 4.651 on 1 and 2 DF, p-value: 0.1638
461 462
462 463 In the notebook, plots are published as the output of the cell::
463 464
464 465 %R plot(X, Y)
465 466
466 467 will create a scatter plot of X bs Y.
467 468
468 469 If cell is not None and line has some R code, it is prepended to
469 470 the R code in cell.
470 471
471 472 Objects can be passed back and forth between rpy2 and python via the -i -o flags in line::
472 473
473 474 In [14]: Z = np.array([1,4,5,10])
474 475
475 476 In [15]: %R -i Z mean(Z)
476 477 Out[15]: array([ 5.])
477 478
478 479
479 480 In [16]: %R -o W W=Z*mean(Z)
480 481 Out[16]: array([ 5., 20., 25., 50.])
481 482
482 483 In [17]: W
483 484 Out[17]: array([ 5., 20., 25., 50.])
484 485
485 486 The return value is determined by these rules:
486 487
487 488 * If the cell is not None, the magic returns None.
488 489
489 490 * If the cell evaluates as False, the resulting value is returned
490 491 unless the final line prints something to the console, in
491 492 which case None is returned.
492 493
493 494 * If the final line results in a NULL value when evaluated
494 495 by rpy2, then None is returned.
495 496
496 497 * No attempt is made to convert the final value to a structured array.
497 498 Use the --dataframe flag or %Rget to push / return a structured array.
498 499
499 500 * If the -n flag is present, there is no return value.
500 501
501 502 * A trailing ';' will also result in no return value as the last
502 503 value in the line is an empty string.
503 504
504 505 The --dataframe argument will attempt to return structured arrays.
505 506 This is useful for dataframes with
506 507 mixed data types. Note also that for a data.frame,
507 508 if it is returned as an ndarray, it is transposed::
508 509
509 510 In [18]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
510 511
511 512 In [19]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
512 513
513 514 In [20]: %%R -o datar
514 515 datar = datapy
515 516 ....:
516 517
517 518 In [21]: datar
518 519 Out[21]:
519 520 array([['1', '2', '3', '4'],
520 521 ['2', '3', '2', '5'],
521 522 ['a', 'b', 'c', 'e']],
522 523 dtype='|S1')
523 524
524 525 In [22]: %%R -d datar
525 526 datar = datapy
526 527 ....:
527 528
528 529 In [23]: datar
529 530 Out[23]:
530 531 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
531 532 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
532 533
533 534 The --dataframe argument first tries colnames, then names.
534 535 If both are NULL, it returns an ndarray (i.e. unstructured)::
535 536
536 537 In [1]: %R mydata=c(4,6,8.3); NULL
537 538
538 539 In [2]: %R -d mydata
539 540
540 541 In [3]: mydata
541 542 Out[3]: array([ 4. , 6. , 8.3])
542 543
543 544 In [4]: %R names(mydata) = c('a','b','c'); NULL
544 545
545 546 In [5]: %R -d mydata
546 547
547 548 In [6]: mydata
548 549 Out[6]:
549 550 array((4.0, 6.0, 8.3),
550 551 dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
551 552
552 553 In [7]: %R -o mydata
553 554
554 555 In [8]: mydata
555 556 Out[8]: array([ 4. , 6. , 8.3])
556 557
557 558 '''
558 559
559 560 args = parse_argstring(self.R, line)
560 561
561 562 # arguments 'code' in line are prepended to
562 563 # the cell lines
563 564
564 565 if cell is None:
565 566 code = ''
566 567 return_output = True
567 568 line_mode = True
568 569 else:
569 570 code = cell
570 571 return_output = False
571 572 line_mode = False
572 573
573 574 code = ' '.join(args.code) + code
574 575
575 576 # if there is no local namespace then default to an empty dict
576 577 if local_ns is None:
577 578 local_ns = {}
578 579
579 580 if args.input:
580 581 for input in ','.join(args.input).split(','):
581 582 try:
582 583 val = local_ns[input]
583 584 except KeyError:
584 585 try:
585 586 val = self.shell.user_ns[input]
586 587 except KeyError:
587 588 raise NameError("name '%s' is not defined" % input)
588 589 self.r.assign(input, self.pyconverter(val))
589 590
590 591 if getattr(args, 'units') is not None:
591 592 if args.units != "px" and getattr(args, 'res') is None:
592 593 args.res = 72
593 594 args.units = '"%s"' % args.units
594 595
595 596 png_argdict = dict([(n, getattr(args, n)) for n in ['units', 'res', 'height', 'width', 'bg', 'pointsize']])
596 597 png_args = ','.join(['%s=%s' % (o,v) for o, v in png_argdict.items() if v is not None])
597 598 # execute the R code in a temporary directory
598 599
599 600 tmpd = tempfile.mkdtemp()
600 601 self.r('png("%s/Rplots%%03d.png",%s)' % (tmpd.replace('\\', '/'), png_args))
601 602
602 603 text_output = ''
603 604 try:
604 605 if line_mode:
605 606 for line in code.split(';'):
606 607 text_result, result, visible = self.eval(line)
607 608 text_output += text_result
608 609 if text_result:
609 610 # the last line printed something to the console so we won't return it
610 611 return_output = False
611 612 else:
612 613 text_result, result, visible = self.eval(code)
613 614 text_output += text_result
614 615 if visible:
615 616 old_writeconsole = ri.get_writeconsole()
616 617 ri.set_writeconsole(self.write_console)
617 618 ro.r.show(result)
618 619 text_output += self.flush()
619 620 ri.set_writeconsole(old_writeconsole)
620 621
621 622 except RInterpreterError as e:
622 623 print(e.stdout)
623 624 if not e.stdout.endswith(e.err):
624 625 print(e.err)
625 626 rmtree(tmpd)
626 627 return
627 628 finally:
628 629 self.r('dev.off()')
629 630
630 631 # read out all the saved .png files
631 632
632 633 images = [open(imgfile, 'rb').read() for imgfile in glob("%s/Rplots*png" % tmpd)]
633 634
634 635 # now publish the images
635 636 # mimicking IPython/zmq/pylab/backend_inline.py
636 637 fmt = 'png'
637 638 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
638 639 mime = mimetypes[fmt]
639 640
640 641 # publish the printed R objects, if any
641 642
642 643 display_data = []
643 644 if text_output:
644 645 display_data.append(('RMagic.R', {'text/plain':text_output}))
645 646
646 647 # flush text streams before sending figures, helps a little with output
647 648 for image in images:
648 649 # synchronization in the console (though it's a bandaid, not a real sln)
649 650 sys.stdout.flush(); sys.stderr.flush()
650 651 display_data.append(('RMagic.R', {mime: image}))
651 652
652 653 # kill the temporary directory
653 654 rmtree(tmpd)
654 655
655 656 # try to turn every output into a numpy array
656 657 # this means that output are assumed to be castable
657 658 # as numpy arrays
658 659
659 660 if args.output:
660 661 for output in ','.join(args.output).split(','):
661 662 self.shell.push({output:self.Rconverter(self.r(output), dataframe=False)})
662 663
663 664 if args.dataframe:
664 665 for output in ','.join(args.dataframe).split(','):
665 666 self.shell.push({output:self.Rconverter(self.r(output), dataframe=True)})
666 667
667 668 for tag, disp_d in display_data:
668 669 publish_display_data(data=disp_d, source=tag)
669 670
670 671 # this will keep a reference to the display_data
671 672 # which might be useful to other objects who happen to use
672 673 # this method
673 674
674 675 if self.cache_display_data:
675 676 self.display_cache = display_data
676 677
677 678 # if in line mode and return_output, return the result as an ndarray
678 679 if return_output and not args.noreturn:
679 680 if result != ri.NULL:
680 681 return self.Rconverter(result, dataframe=False)
681 682
682 683 __doc__ = __doc__.format(
683 684 R_DOC = dedent(RMagics.R.__doc__),
684 685 RPUSH_DOC = dedent(RMagics.Rpush.__doc__),
685 686 RPULL_DOC = dedent(RMagics.Rpull.__doc__),
686 687 RGET_DOC = dedent(RMagics.Rget.__doc__)
687 688 )
688 689
689 690
690 691 def load_ipython_extension(ip):
691 692 """Load the extension in IPython."""
693 warnings.warn("The rmagic extension in IPython is deprecated in favour of "
694 "rpy2.ipython. If available, that will be loaded instead.")
695 try:
696 import rpy2.ipython
697 except ImportError:
698 pass # Fall back to our own implementation for now
699 else:
700 return rpy2.ipython.load_ipython_extension(ip)
701
692 702 ip.register_magics(RMagics)
693 703 # Initialising rpy2 interferes with readline. Since, at this point, we've
694 704 # probably just loaded rpy2, we reset the delimiters. See issue gh-2759.
695 705 if ip.has_readline:
696 706 ip.readline.set_completer_delims(ip.readline_delims)
General Comments 0
You need to be logged in to leave comments. Login now