This post provides a brief introduction to calling Python from R through Rcpp. The
official Python documentation explains how to
embed python into C/C++ applications. Moreover, the
Boost.Python library
provides seamless interoperability between C++ and the Python programming
language. Similarlly, Rcpp provides interoperability between C++ and
R. Therefore, it is not hard to call Python from R through Rcpp and Boost.Python.
Although there is a package
rPython which provides an
interface to Python from R through Java, it is interesting to try to connect
R and Python via C++.
In this article, we show how to call Python 2.7 from R on Ubuntu.
Hello World
The most difficult thing is to establish a development environment. On Ubuntu,
we need to install the following packages to build via embeded Python:
Then, we pass the following flags to the compiler:
The following hello world should then work:
Let’s call them in R:
Today is Thu Apr 2 11:32:17 2015
It shows that the hello_python function successfully initializes the Python
engine and runs the Python script through PyRun_SimpleString.
Type Conversion
With Boost.Python and Rcpp, we can easily transfer the data between R and
Python. The following C codes transfer the R IntegerVector to Python
List:
<pointer: 0x8e0b410>
The pointer refers to the memory of the transformed Python object.
Call Python Function
The following example shows how to define a function in Python and expose it in R.
1
2
3
4
5
6
7
8
9
10
Error Handling
Errors in the Python engine can be handled easily by the C++ try/catch
idiom as the following example shows:
KeyError: 'print_lists'
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 5, in <module>
from apport.report import Report
File "/usr/lib/python2.7/dist-packages/apport/report.py", line 16, in <module>
from xml.parsers.expat import ExpatError
File "/usr/lib/python2.7/xml/parsers/expat.py", line 4, in <module>
from pyexpat import *
ImportError: /usr/lib/python2.7/lib-dynload/pyexpat.i386-linux-gnu.so: undefined symbol: _Py_ZeroStruct
Original exception was:
KeyError: 'print_lists'
Summary
These examples show how to integrate Python and R with Rcpp and Boost.Python.
It relied on two C++ libraries which ease the integration work greatly: Rcpp
for R, and Boost.Python for Python. The core steps discussed above are
initializing the engine (Hello World), transforming the data (Type
Conversion), exposing functions (Call Python Function), and handling
errors properly (Error Handling).