- この記事の「なんちゃってRパッケージ」はこちら Here is the github containing files and directories handled in this note.
- Cの関数を取り込むには、C関数をダイナミック・リンク・ライブラリにしつつ、それを呼び出す、という仕組みにする必要がある Let's use C functions in your shareable package. When you incude C functions, they should be converted into dynamic link library and the library should be called from your R function.
- そのために、さらにちょっと工夫が必要 A bit tasks are necessary for it.
- 一つの工夫はC関係ファイルの置き場をsrcディレクトリとする One task is to have a directory "src" in the working directory.
- ダイナミック・リンク・ライブラリを呼び出しますよということを1文書く必要がある The other is to add a line indicating to use the dynamic link library.
- こちらにある、Cで書かれたreverse処理とそれを呼び出すRの関数を拝借する For our practice, borrow a C file and its wrapper function here.
- まずはCファイル。RそのものがCを使って作られており、その関係から、2つのヘッダincludeを書くのがルール The C file has header lines that are something related to the fact that R is developed with C.
#include <R.h>
#include <Rdefines.h>
SEXP reverse(SEXP x)
{
PROTECT(x = AS_INTEGER(x));
int n = GET_LENGTH(x);
if (n <= 0) {
UNPROTECT(1);
return R_NilValue;
}
SEXP y;
PROTECT(y = NEW_INTEGER(n));
const int *px = INTEGER_POINTER(x);
int *py = INTEGER_POINTER(y) + n - 1;
for (int i = 0;i < n; ++i)
*py-- = *px++;
UNPROTECT(2);
return y;
}
-
- 次いで、Rファイル。もちろん@exportしないと「使える関数」としてNAMESPACEファイルに書き込んでくれないから、それを書く。さらに、今作っているry3というパッケージが作るダイナミック・リンク・ライブラリを使うのですよ、という宣言 @useDynLib ry3を書く(ただし、いくつものC関数を呼び出すR関数があるときは、この宣言は1か所書いておけばよい。 Then R function file. This R function should be "@export" 'ed to be used for NAMESPACE issue. Now write a line indicating that the dynamic link library "ry3" is to be made and it should be called. This line should appear in only one of multiple R function files
@export
reverse <- function(x) {
.Call("reverse", x)
}
- さて。srcフォルダが必要なのだが、これもdevtoolsで作れる。The src directory can be created by a function in devtools.
- いつものようにry3フォルダ配下に諸ファイル・フォルダを切り、そのあと、「(Rcppでやるように)C,C++,fortranなどを使いますよ」ということを知らせる関数use_rcpp()を打つとsrcフォルダができる Because packages using Rcpp should have the src directory, devtools has a function named "use_rcpp()" for the generation of src directory and it works for C or fortran.
create("ry3")
use_rcpp()
-
- Cファイルはsrcフォルダに置き、.CallするR関数はRフォルダに置く Put your C files (including header files if any) in src directory and your R files in R directory.
- そのうえで Then do as;
document()
-
- そうすると、NAMASPACEファイルに You will find a line below in NAMESPACE file.
useDynLib(ry3)
-
- という1行が入り、これが「ダイナミック・リンク・ライブラリを使いますよ」という宣言の役に立つ This tells R that the dynamic link library to be generated should be called.
- このようにして作るry3配下そっくりを、githubのレポジトリのクローンフォルダに置いて、それをレポジトリにpushすれば出来上がり All under ry3 directory should be copy-and-pasted into the clone-directory and push them into github.
- 使うときは When you use the package, do below.
> install_github("ryamada22/ry3")
> library(ry3)
> reverse(1:10)
[1] 10 9 8 7 6 5 4 3 2 1
> reverse
function (x)
{
.Call("reverse", x)
}
<environment: namespace:ry3>