使用C / Rcpp检查封闭呼叫中是否缺少参数

时间:2015-03-26 16:32:32

标签: r rcpp

我需要使用用C或Rcpp编写的函数来检查封闭的R调用是否缺少参数。这可能吗?如果是这样的话?

以下是我在阅读了一些R源代码后想出的内容。

Rcpp::cppFunction('
void check_missing(SEXP e) {
  Rcpp::Environment env(e);
  Rcpp::CharacterVector names = env.ls(false);
  SEXP unevaluatedArg;
  for(int i=0; i<names.length(); i++){
    std::string name = as<std::string>(names[i]);
    Rcpp::Rcout << "argument - " << name << std::endl;
    SEXP nameSym = Rf_install(name.c_str());
    unevaluatedArg = Rf_findVarInFrame(e, nameSym);
    if (MISSING(unevaluatedArg) || CAR(unevaluatedArg) == R_MissingArg) {
      Rcpp::Rcout << "missing" << std::endl;
    }
  }
}')
f <- function(x, y) {
  check_missing(environment())
}
f()

但不知何故,MISSING(unevaluatedArg) || CAR(unevaluatedArg) == R_MissingArg永远不会评估为TRUE。是因为我在列举环境吗?或者出了什么问题?

P.S。我有理由在C中执行此操作,而不是使用标准missing,因为在我的项目check_missing中需要应用于任何环境,在这里我只给出了一个简化的案例。

1 个答案:

答案 0 :(得分:4)

您需要if ( unevaluatedArg == R_MissingArg){ ... }。这个稍微修改过的代码对我有用:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
void check_missing(SEXP e) {
  Rcpp::Environment env(e);
  Rcpp::CharacterVector names = env.ls(false);
  SEXP unevaluatedArg;
  for(int i=0; i<names.length(); i++){
    std::string name = as<std::string>(names[i]);
    Rcpp::Rcout << "argument - " << name << std::endl;
    SEXP nameSym = Rf_install(name.c_str());
    unevaluatedArg = Rf_findVarInFrame(e, nameSym);   
    if ( unevaluatedArg == R_MissingArg) {
      Rcpp::Rcout << "missing" << std::endl;
    }
  }
}

,并提供:

> f()
argument - x
missing
argument - y
missing

> f(1)
argument - x
argument - y
missing