Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add REPL-like printing of final/return value to %%R cell magic #4017

Merged
merged 4 commits into from
Aug 14, 2013
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 28 additions & 11 deletions IPython/extensions/rmagic.py
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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if visible: doesn't need brackets in Python ;-)

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