C function; No helps; github & R package

  • この記事の「なんちゃって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>

/* Take an int vector and reverse it. */
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
#' @useDynLib ry3
#' @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>