14

関数から可変数の引数を C/C++ に渡したいのですが、引数を評価せずに残しておき、同時に R で計算を実行したくありません (C/C++ の呼び出しは別として)。つまりsubstitute、R 関数を呼び出したくありません。私が使用できると思ったこのための1つのオプションは.External、次のようにsmthを行うことです:

R_fn = function(...) .External("cpp_fn", ...)

...
# and in C code:
SEXP cpp_fn (SEXP arglist) {
}

ただし、.Externalで引数を評価し...ているので、次のようなものを試してみると

rm(x, y) # just making sure these don't exist

R_fn(x*y)

R が関数に送信するx*y に評価しようとしているため、エラーが発生します。

対照的に、R では次のように動作します。

f = function(...) g(...)
g = function(x, ...) print(substitute(x))

f(x*y*z)
# x * y * z

他にどのようなオプションがありますか? 明らかに、R自体が多くの関数、たとえばsubstituteそれ自体に対して行うように行うことが可能ですが、その方法がわかりません。rcppこれを最終的に使用する予定があるため、タグを追加しましたRcpp

4

1 に答える 1

5

1 つの可能性は、何をするかということmatch.callです (その方向に向けてくれた Ricardo Saporta に感謝します)。これには、R ソース コードからいくつかの定義をコピー アンド ペーストする必要がありますが、ここでは行いませんが、基本的な考え方は、呼び出し元の関数をそこから取得し、R_GlobalContextそこから関数の引数を抽出することです。ラフスケッチは次のとおりです。

R_fn = function(...) .Call("cpp_fn")

// and in C++ code
Language cpp_fn() {
  SEXP sysp = ((RCNTXT*)R_GlobalContext)->sysparent;
  RCNTXT *cptr = (RCNTXT*)R_GlobalContext;

  while (cptr != NULL) {
    if (cptr->callflag & CTXT_FUNCTION && cptr->cloenv == sysp)
      break;
    cptr = cptr->nextcontext;
  }
  cptr = cptr->nextcontext; // because this is called from .Call and not from R_fn

  // and now cptr->promargs has the unevaluated arguments to do as one pleases
  // e.g.
  Language firstArg(R_PromiseExpr(CAR(cptr->promargs)));

  return firstArg;
}
于 2013-10-31T16:16:48.953 に答える