Skip to content

Commit

Permalink
Merge pull request #4017 from gmbecker/PR_rmagic2
Browse files Browse the repository at this point in the history
Add REPL-like printing of final/return value to %%R cell magic
  • Loading branch information
takluyver committed Aug 14, 2013
2 parents 6a4cf5b + 247f277 commit 681735e
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions IPython/extensions/rmagic.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,28 @@ def __init__(self, shell, Rconverter=Rconverter,

def eval(self, line):
'''
Parse and evaluate a line with rpy2.
Returns the output to R's stdout() connection
and the value of eval(parse(line)).
Parse and evaluate a line of R code with rpy2.
Returns the output to R's stdout() connection,
the value generated by evaluating the code, and a
boolean indicating whether the return value would be
visible if the line of code were evaluated in an R REPL.
R Code evaluation and visibility determination are
done via an R call of the form withVisible({<code>})
'''
old_writeconsole = ri.get_writeconsole()
ri.set_writeconsole(self.write_console)
try:
value = ri.baseenv['eval'](ri.parse(line))
res = ro.r("withVisible({%s})" % line)
value = res[0] #value (R object)
visible = ro.conversion.ri2py(res[1])[0] #visible (boolean)
except (ri.RRuntimeError, ValueError) as exception:
warning_or_other_msg = self.flush() # otherwise next return seems to have copy of error
raise RInterpreterError(line, str_to_unicode(str(exception)), warning_or_other_msg)
text_output = self.flush()
ri.set_writeconsole(old_writeconsole)
return text_output, value
return text_output, value, visible

def write_console(self, output):
'''
Expand Down Expand Up @@ -413,13 +421,16 @@ def R(self, line, cell=None, local_ns=None):
In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
Out[9]: array([ 4.25])
As a cell, this will run a block of R code, without bringing anything back by default::
In cell mode, this will run a block of R code. The resulting value
is printed if it would printed be when evaluating the same code
within a standard R REPL.
Nothing is returned to python by default in cell mode.
In [10]: %%R
....: Y = c(2,4,3,9)
....: print(summary(lm(Y~X)))
....:
....: summary(lm(Y~X))
Call:
lm(formula = Y ~ X)
Expand Down Expand Up @@ -580,14 +591,20 @@ def R(self, line, cell=None, local_ns=None):
try:
if line_mode:
for line in code.split(';'):
text_result, result = self.eval(line)
text_result, result, visible = self.eval(line)
text_output += text_result
if text_result:
# the last line printed something to the console so we won't return it
return_output = False
else:
text_result, result = self.eval(code)
text_result, result, visible = self.eval(code)
text_output += text_result
if visible:
old_writeconsole = ri.get_writeconsole()
ri.set_writeconsole(self.write_console)
ro.r.show(result)
text_output += self.flush()
ri.set_writeconsole(old_writeconsole)

except RInterpreterError as e:
print(e.stdout)
Expand Down

0 comments on commit 681735e

Please sign in to comment.