我需要使用用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
中需要应用于任何环境,在这里我只给出了一个简化的案例。
答案 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