Ejemplo n.º 1
0
    def setUp(self):
        self.console = rinterface.get_writeconsole_regular()

        def noconsole(x):
            pass

        rinterface.set_writeconsole_regular(noconsole)
Ejemplo n.º 2
0
    def eval(self, code):
        """
        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_string), and this entire expression needs to
        be evaluated in R (we can't use rpy2 function proxies here, as
        withVisible is a LISPy R function).

        """
        old_writeconsole_regular = ri.get_writeconsole_regular()
        ri.set_writeconsole_regular(self.write_console_regular)
        try:
            # Need the newline in case the last line in code is a comment
            value, visible = ro.r("withVisible({%s\n})" % code)
        except (ri.RRuntimeError, ValueError) as exception:
            warning_or_other_msg = self.flush(
            )  # otherwise next return seems to have copy of error
            raise RInterpreterError(code, str(exception), warning_or_other_msg)
        text_output = self.flush()
        ri.set_writeconsole_regular(old_writeconsole_regular)
        return text_output, value, visible[0]
Ejemplo n.º 3
0
    def eval(self, code):
        '''
        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_string), and this entire expression needs to
        be evaluated in R (we can't use rpy2 function proxies here, as
        withVisible is a LISPy R function).

        '''
        old_writeconsole_regular = ri.get_writeconsole_regular()
        ri.set_writeconsole_regular(self.write_console_regular)
        try:
            # Need the newline in case the last line in code is a comment
            value, visible = ro.r("withVisible({%s\n})" % code)
        except (ri.RRuntimeError, ValueError) as exception:
            warning_or_other_msg = self.flush() # otherwise next return seems to have copy of error
            raise RInterpreterError(code, str_to_unicode(str(exception)), warning_or_other_msg)
        text_output = self.flush()
        ri.set_writeconsole_regular(old_writeconsole_regular)
        return text_output, value, visible[0]
Ejemplo n.º 4
0
    def setUp(self):
        self.console = rinterface.get_writeconsole_regular()

        def noconsole(x):
            pass

        rinterface.set_writeconsole_regular(noconsole)
Ejemplo n.º 5
0
    def testSetWriteConsoleRegular(self):
        buf = []
        def f(x):
            buf.append(x)

        rinterface.set_writeconsole_regular(f)
        self.assertEqual(rinterface.get_writeconsole_regular(), f)
        code = rinterface.SexpVector(["3", ], rinterface.STRSXP)
        rinterface.baseenv["print"](code)
        self.assertEqual('[1] "3"\n', str.join('', buf))
Ejemplo n.º 6
0
    def testSetWriteConsoleRegular(self):
        buf = []

        def f(x):
            buf.append(x)

        rinterface.set_writeconsole_regular(f)
        self.assertEqual(rinterface.get_writeconsole_regular(), f)
        code = rinterface.SexpVector([
            "3",
        ], rinterface.STRSXP)
        rinterface.baseenv["print"](code)
        self.assertEqual('[1] "3"\n', str.join('', buf))
Ejemplo n.º 7
0
    def R(self, line, cell=None, local_ns=None):
        """
        Execute code in R, optionally returning results to the Python runtime.

        In line mode, this will evaluate an expression and convert the returned
        value to a Python object.  The return value is determined by rpy2's
        behaviour of returning the result of evaluating the final expression.

        Multiple R expressions can be executed by joining them with semicolons::

            In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
            Out[9]: array([ 4.25])

        In cell mode, this will run a block of R code. The resulting value
        is printed if it would be printed 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)
               ....: summary(lm(Y~X))

            Call:
            lm(formula = Y ~ X)

            Residuals:
                1     2     3     4
             0.88 -0.24 -2.28  1.64

            Coefficients:
                        Estimate Std. Error t value Pr(>|t|)
            (Intercept)   0.0800     2.3000   0.035    0.975
            X             1.0400     0.4822   2.157    0.164

            Residual standard error: 2.088 on 2 degrees of freedom
            Multiple R-squared: 0.6993,Adjusted R-squared: 0.549
            F-statistic: 4.651 on 1 and 2 DF,  p-value: 0.1638

        In the notebook, plots are published as the output of the cell::

            %R plot(X, Y)

        will create a scatter plot of X bs Y.

        If cell is not None and line has some R code, it is prepended to
        the R code in cell.

        Objects can be passed back and forth between rpy2 and python via the -i -o flags in line::

            In [14]: Z = np.array([1,4,5,10])

            In [15]: %R -i Z mean(Z)
            Out[15]: array([ 5.])


            In [16]: %R -o W W=Z*mean(Z)
            Out[16]: array([  5.,  20.,  25.,  50.])

            In [17]: W
            Out[17]: array([  5.,  20.,  25.,  50.])

        The return value is determined by these rules:

        * If the cell is not None (i.e., has contents), the magic returns None.

        * If the final line results in a NULL value when evaluated
          by rpy2, then None is returned.

        * No attempt is made to convert the final value to a structured array.
          Use %Rget to push a structured array.

        * If the -n flag is present, there is no return value.

        * A trailing ';' will also result in no return value as the last
          value in the line is an empty string.
        """

        args = parse_argstring(self.R, line)

        # arguments 'code' in line are prepended to
        # the cell lines

        if cell is None:
            code = ''
            return_output = True
            line_mode = True
        else:
            code = cell
            return_output = False
            line_mode = False

        code = ' '.join(args.code) + code

        # if there is no local namespace then default to an empty dict
        if local_ns is None:
            local_ns = {}

        if args.converter is None:
            converter = self.converter
        else:
            try:
                converter = local_ns[args.converter]
            except KeyError:
                try:
                    converter = self.shell.user_ns[args.converter]
                except KeyError:
                    raise NameError("name '%s' is not defined" %
                                    args.converter)
            if not isinstance(converter, Converter):
                raise ValueError(
                    "'%s' must be a %s object (but it is a %s)." %
                    (args.converter, Converter, type(localconverter)))

        if args.input:
            for input in ','.join(args.input).split(','):
                try:
                    val = local_ns[input]
                except KeyError:
                    try:
                        val = self.shell.user_ns[input]
                    except KeyError:
                        raise NameError("name '%s' is not defined" % input)
                with localconverter(converter) as cv:
                    ro.r.assign(input, val)

        tmpd = self.setup_graphics(args)

        text_output = ''
        try:
            if line_mode:
                for line in code.split(';'):
                    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, visible = self.eval(code)
                text_output += text_result
                if visible:
                    old_writeconsole_regular = ri.get_writeconsole_regular()
                    ri.set_writeconsole_regular(self.write_console_regular)
                    ro.r.show(result)
                    text_output += self.flush()
                    ri.set_writeconsole_regular(old_writeconsole_regular)

        except RInterpreterError as e:
            # TODO: Maybe we should make this red or something?
            print(e.stdout)
            if not e.stdout.endswith(e.err):
                print(e.err)
            if tmpd:
                rmtree(tmpd)
            return
        finally:
            if self.device in ['png', 'svg']:
                ro.r('dev.off()')

        if text_output:
            # display_data.append(('RMagic.R', {'text/plain':text_output}))
            publish_display_data(data={'text/plain': text_output},
                                 source='RMagic.R')
        # publish the R images
        if self.device in ['png', 'svg']:
            display_data, md = self.publish_graphics(tmpd, args.isolate_svgs)

            for tag, disp_d in display_data:
                publish_display_data(data=disp_d, source=tag, metadata=md)

            # kill the temporary directory - currently created only for "svg"
            # and "png" (else it's None)
            rmtree(tmpd)

        if args.output:
            with localconverter(converter) as cv:
                for output in ','.join(args.output).split(','):
                    output_ipy = ro.globalenv.get(output)
                    self.shell.push({output: output_ipy})

        # this will keep a reference to the display_data
        # which might be useful to other objects who happen to use
        # this method

        if self.cache_display_data:
            self.display_cache = display_data

        # We're in line mode and return_output is still True,
        # so return the converted result
        if return_output and not args.noreturn:
            if result is not ri.NULL:
                with localconverter(converter) as cv:
                    res = cv.ri2py(result)
                return res
Ejemplo n.º 8
0
    def R(self, line, cell=None, local_ns=None):
        '''
        Execute code in R, optionally returning results to the Python runtime.

        In line mode, this will evaluate an expression and convert the returned
        value to a Python object.  The return value is determined by rpy2's
        behaviour of returning the result of evaluating the final expression.

        Multiple R expressions can be executed by joining them with semicolons::

            In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
            Out[9]: array([ 4.25])

        In cell mode, this will run a block of R code. The resulting value
        is printed if it would be printed 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)
               ....: summary(lm(Y~X))

            Call:
            lm(formula = Y ~ X)

            Residuals:
                1     2     3     4
             0.88 -0.24 -2.28  1.64

            Coefficients:
                        Estimate Std. Error t value Pr(>|t|)
            (Intercept)   0.0800     2.3000   0.035    0.975
            X             1.0400     0.4822   2.157    0.164

            Residual standard error: 2.088 on 2 degrees of freedom
            Multiple R-squared: 0.6993,Adjusted R-squared: 0.549
            F-statistic: 4.651 on 1 and 2 DF,  p-value: 0.1638

        In the notebook, plots are published as the output of the cell::

            %R plot(X, Y)

        will create a scatter plot of X bs Y.

        If cell is not None and line has some R code, it is prepended to
        the R code in cell.

        Objects can be passed back and forth between rpy2 and python via the -i -o flags in line::

            In [14]: Z = np.array([1,4,5,10])

            In [15]: %R -i Z mean(Z)
            Out[15]: array([ 5.])


            In [16]: %R -o W W=Z*mean(Z)
            Out[16]: array([  5.,  20.,  25.,  50.])

            In [17]: W
            Out[17]: array([  5.,  20.,  25.,  50.])

        The return value is determined by these rules:

        * If the cell is not None (i.e., has contents), the magic returns None.

        * If the final line results in a NULL value when evaluated
          by rpy2, then None is returned.

        * No attempt is made to convert the final value to a structured array.
          Use %Rget to push a structured array.

        * If the -n flag is present, there is no return value.

        * A trailing ';' will also result in no return value as the last
          value in the line is an empty string.
        '''

        args = parse_argstring(self.R, line)

        # arguments 'code' in line are prepended to
        # the cell lines

        if cell is None:
            code = ''
            return_output = True
            line_mode = True
        else:
            code = cell
            return_output = False
            line_mode = False

        code = ' '.join(args.code) + code

        # if there is no local namespace then default to an empty dict
        if local_ns is None:
            local_ns = {}

        if args.converter is None:
            pass
        else:
            try:
                localconverter = local_ns[args.converter]
            except KeyError:
                try:
                    localconverter = self.shell.user_ns[args.converter]
                except KeyError:
                    raise NameError("name '%s' is not defined" % args.converter)
            if not isinstance(localconverter, Converter):
                raise ValueError("'%s' must be a Converter object.")
            
        if args.input:
            for input in ','.join(args.input).split(','):
                try:
                    val = local_ns[input]
                except KeyError:
                    try:
                        val = self.shell.user_ns[input]
                    except KeyError:
                        raise NameError("name '%s' is not defined" % input)
                if args.converter is None:
                    ro.r.assign(input, self.pyconverter(val))
                else:
                    ro.r.assign(input, localconverter.py2ri(val))

        tmpd = self.setup_graphics(args)

        text_output = ''
        try:
            if line_mode:
                for line in code.split(';'):
                    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, visible = self.eval(code)
                text_output += text_result
                if visible:
                    old_writeconsole_regular = ri.get_writeconsole_regular()
                    ri.set_writeconsole_regular(self.write_console_regular)
                    ro.r.show(result)
                    text_output += self.flush()
                    ri.set_writeconsole_regular(old_writeconsole_regular)

        except RInterpreterError as e:
            # XXX - Maybe we should make this red or something?
            print(e.stdout)
            if not e.stdout.endswith(e.err):
                print(e.err)
            if tmpd: rmtree(tmpd)
            return
        finally:
            if self.device in ['png', 'svg']:
                ro.r('dev.off()')

        if text_output:
            # display_data.append(('RMagic.R', {'text/plain':text_output}))
            publish_display_data(data={'text/plain':text_output}, source='RMagic.R')
        # publish the R images
        if self.device in ['png', 'svg']:
            display_data, md = self.publish_graphics(tmpd, args.isolate_svgs)

            for tag, disp_d in display_data:
                publish_display_data(data=disp_d, source=tag, metadata=md)

            # kill the temporary directory - currently created only for "svg"
            # and "png" (else it's None)
            rmtree(tmpd)

        if args.output:
            for output in ','.join(args.output).split(','):
                if args.converter is None:
                    output_ipy = converter.ri2py(ri.globalenv.get(output))
                else:
                    output_ipy = localconverter.ri2py(ri.globalenv.get(output))
                self.shell.push({output: output_ipy })


        # this will keep a reference to the display_data
        # which might be useful to other objects who happen to use
        # this method

        if self.cache_display_data:
            self.display_cache = display_data

        # We're in line mode and return_output is still True, 
        # so return the converted result
        if return_output and not args.noreturn:
            if result is not ri.NULL:
                if args.converter is None:
                    return converter.ri2py(result)
                else:
                    return localconverter.ri2py(result)