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

Check if there are missing arguments in enclosing call using C/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需要应用于任何环境,这里我只给出一个简化的案例。

你需要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