14. 様々な関数

Rdefines.hに含まれるマクロのほか、Rinternals.hなどのほかのヘッダーファイルにもマクロが用意されている。

いずれはすべてを扱いたいが、いくつかの関数にしぼって紹介することにする。

14.1. length

  • length

ベクトルの要素数を取得する。返り値は、構造体vecsxpの要素で整数値のlengthにアクセスしたものとなる。

引数は、ポインタ。

14.2. コード

#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>

SEXP return_length(SEXP arg_p) {
    SEXP len;
    int len_i;

    len_i = length(arg_p);

    len = PROTECT(NEW_INTEGER(1));

    INTEGER_POINTER(len)[0] = len_i;

    UNPROTECT(1);
    return len;
}
dyn.load("return_length.so")

wrap_len <- function(vec) {

    .Call("return_length", vec)

}

wrap_len(1:6)
# [1] 6

wrap_len("Hello")
# [1] 1

wrap_len(NULL)
# [1] 0

14.3. ncols, nrows

  • ncols
  • nrows

返り値として、int型を返す。

引数は、ポインタ。

14.4. コード

#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>

SEXP return_cr(SEXP arg_p) {
    SEXP res;

    res = PROTECT(NEW_INTEGER(2));

    int row, col;

    row = nrows(arg_p);
    col = ncols(arg_p);

    INTEGER_POINTER(res)[0] = row;
    INTEGER_POINTER(res)[1] = col;

    UNPROTECT(1);
    return res;
}
dyn.load("return_cr.so")

ncol_nrow <- function(vec) {

    .Call("return_cr", vec)

}

num <- 1:6

dim(num) <- c(2, 3)

ncol_nrow(num)
# [1] 2 3

14.5. mkChar

  • mkChar

文字列を生成する。文字列を直接あつかうのはポインタが絡むため面倒だが、SEXPを返してくれる便利な関数。

14.6. コード

#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>

SEXP init_msg() {
    SEXP inited;

    inited = PROTECT(NEW_CHARACTER(1));

    CHARACTER_POINTER(inited)[0] = mkChar("This object is initialized in C.");

    UNPROTECT(1);
    return inited;
}
dyn.load("init_msg.so")

init_c <- function() {
    RES <- .Call("init_msg")

    list(res = RES)
}

hoge <- init_c()

hoge$res
# [1] "This object is initialized in C."