内容简介:Library selection for data science is a different story. Although there are some libraries available, such asThis article shows how to embed an R interpreter inside a D program, pass data between the two languages, execute arbitrary R code from within a D
D is a good language for data science. The advantages include a pleasant syntax, interoperability with C (in many cases as simple as adding an #include
directive to import a C header filevia the dpp tool), C-like speed, a large standard library, static typing, built-in unit tests and documentation generation, and a garbage collector that’s there when you want it but can be avoided when you don’t.
Library selection for data science is a different story. Although there are some libraries available, such as those provided by the mir project , the available functionality is extremely limited compared with languages like R and Python. The good news is that it’s possible to call functions in either language from D.
This article shows how to embed an R interpreter inside a D program, pass data between the two languages, execute arbitrary R code from within a D program, and call the R interface to C, C++, and Fortran libraries from D. Although I only provide examples for Linux, the same steps apply for Windows if you’re using WSL, and with minor modifications to the DUB package file, everything should work on macOS. Although it is possible to do so, I don’t talk about calling D functions from R, and I don’t include any discussion of interoperability with Python. (This is normally done using pyd .)
Dependencies
The following three dependencies should be installed:
- R package RInsideC
- R package embedr
It’s assumed that anyone reading this post already has R installed or can install it if they don’t. The RInsideC package is a slightly modified version of the excellent RInside project of Dirk Eddelbuettel and Romain Francois. RInside provides a C++ interface to R. The modifications provide a C interface so that R can be called from any language capable of calling C functions. Install the package using devtools :
library(devtools) install_bitbucket("bachmeil/rinsidec")
The embedr package provides the necessary functions to work with R from within D. That package is also installed with devtools:
install_bitbucket("bachmeil/embedr")
A First Program
The easiest way to do the compilation is to use D’s package manager, called DUB . From within your project directory, open R and create a project skeleton:
library(embedr) dubNew()
This will create a /src
subdirectory to hold your project’s source code if it doesn’t already exist, add a file called r.d
to /src
and create a dub.sdl
file in the project directory. Create a file in the /src
directory called hello.d
, containing the following program:
import embedr.r; void main() { evalRQ(`print("Hello, World!")`); }
From the terminal, in the project directory (the one holding dub.sdl
, not the /src
subdirectory), enter
dub run
This will print out “Hello, World!”. The important thing to realize is that even though you just used DUB to compile and run a D program, it was R that printed “Hello, World!” to the screen.
Executing R Code From D
There are two ways to execute R code from a D program. evalR
executes a string in R and prints the output to the screen, while evalRQ
does the same thing but suppresses the output. evalRQ
also accepts an array of strings that are executed sequentially.
Create a new project directory and run dubNew
inside it, as you did for the first example. In the src/
subdirectory, add a file named reval.d
:
import embedr.r; import std.stdio; void main() { // Example 1 evalRQ(`print(3+2)`); // evaluates to 5 in R, R prints the output [1] 5 to the screen // Example 2 writeln(evalR(`3+2`).scalar); // evaluates to 5 in R, output is 5 // Example 3 evalRQ(`3+2`); // evaluates to 5 in R, but there is no output // Example 4 evalRQ([`x <- 3`, `y <- 2`, `z <- x+y`, `print(z)`]); // evaluates this code in R but prints nothing to the screen }
Example 1 tells R to print the sum of 3
and 2
. Because we use evalRQ
, no output is returned to D, but R is able to print to the screen. Example 2 evaluates 3+2
in R and returns the output to D in the form of an Robj
. evalR(``3+2``).scalar
executes 3+2
inside R, captures the output in an Robj
, and converts the Robj
into a double
holding the value 5
. This value is passed to the writeln
function and printed to the screen. Example 3 doesn’t output anything, because evalRQ
does not return any output, and R isn’t being told to print anything to the screen. Example 4 executes the four strings in the array sequentially, returning nothing to D, but the last tells R to print the value of z
to the screen.
There’s not much more to say about executing R code from D. You can execute any valid R code from D, and if there’s an error, it will be caught and printed to the screen. Graphical output is automatically captured in a PDF file. To work interactively with R, or if it’s sufficient to save the results to a text file and read them into D, this is all you need to know. The more interesting cases involve passing data between D and R, and for the times when there is no alternative, using the R interface to call directly into C, C++, or Fortran libraries.
Passing Data Between D and R
A little background is needed to understand how to pass data between D and R. Everything in R is represented as a C struct named SEXPREC
, and a pointer to a SEXPREC
struct is called a SEXP
in the R source code. Those names r
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人月神话(40周年中文纪念版)
(美) 布鲁克斯(Brooks, F. P.) 著 / UML China翻译组,汪颖 译 / 清华大学出版社 / 2015-4-1 / 68.00元
在软件领域,很少能有像《人月神话》一样具有深远影响力和畅销不衰的著作。Brooks博士为人们管理复杂项目提供了最具洞察力的见解,既有很多发人深省的观点,又有大量软件工程的实践。本书内容来自Brooks博士在IBM公司SYSTEM/360家族和OS/360中的项目管理经验,该项目堪称软件开发项目管理的典范。该书英文原版一经面世,即引起业内人士的强烈反响,后又译为德、法、日、俄、中、韩等多种文字,全球......一起来看看 《人月神话(40周年中文纪念版)》 这本书的介绍吧!