Rcpp 数据框不能根据上下文转换为 bool

Rcpp dataframe not contextually convertible to bool

使用数据帧(来自 Rcpp)时,您通常如何处理默认值?

这是我尝试过的:

// [[Rcpp::export]]
Rcpp::DataFrame FindFormula(Rcpp::DataFrame(masslist),Rcpp::DataFrame(params)=NULL
  ,Rcpp::DataFrame(isotope)=NULL) {

  // access masslist by column
  Rcpp::NumericVector mass = masslist["exp mass"];
  Rcpp::IntegerVector  mag = masslist["intensity"];

  // default params, if no entry
  if (params==NULL)
  {
    // access params by column
    Rcpp::StringVector param = params["value"];

    // assign param variables (string to value)
    double tol = std::stod(param[0]);
    int charge = std::stoi(param[1]);
  }
  else
  {
    // default params
    double tol = 0.4;
    int charge =   0;
  }

params==NULL 表达式是我得到错误的地方。如果我将 params 定义为 int 或数组,这似乎有效。我没有写太多 C++ 并且是 Rcpp 的新手,所以我很感激任何对数据帧有更多了解的人。

您的代码中有几个语法问题值得指出。首先,NULL 比 R 中的 非常 different meaning in C/C++ - 不要像上面那样使用它。您可以在您的 Rcpp 代码中使用 R_NilValue 来表示 R 的 NULL。此外,您的函数参数声明不正确。从句法上讲,这条语句 -

Rcpp::DataFrame(masslist)

正在(大概)另一个名为 masslistDataFrame 对象上调用 DataFrame class 的构造函数/复制构造函数,但这不是你想要的,而且它无论如何都不会编译。您的函数签名(广义上讲)需要更像

ReturnType function_name(ParamType1 param1, ParamType2 param2, ...)

或者,使用默认参数,

ReturnType function_name(ParamType1 param1 = p1, ParamType2 param2 = p2, ...)

其中 p1p2 是实际值,不是变量。


在你的情况下,我真的认为编写一个 没有 具有默认参数的 Rcpp 函数并从 R 中指定默认值的简单包装函数调用它要简单得多.例如,

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::DataFrame FindFormulaCpp(Rcpp::DataFrame masslist_,
                             Rcpp::DataFrame params_,
                             Rcpp::DataFrame isotope_) {
  // do whatever

  return Rcpp::DataFrame::create(Rcpp::Named("Result") = Rcpp::rnorm(5));
}


/*** R

masslist <- data.frame(x = 1:5, y = 6:10)
params <- data.frame(a = rnorm(5), b = 1:5)
isotope <- data.frame(e = letters[1:5])

RFindFormula <- function(arg1 = masslist, arg2 = params, arg3 = isotope) {
  FindFormulaCpp(arg1, arg2, arg3)
}

R> RFindFormula()
# Result
# 1  0.84583003
# 2 -0.65687178
# 3 -1.05891172
# 4 -0.06872972
# 5 -0.19695890

*/

但是,如果您坚持从 C++ 处理这个问题,您可以做一些事情来达到这种效果:

#include <Rcpp.h>

struct my_defaults {
  Rcpp::DataFrame masslist, params, isotope;
  my_defaults() {
    masslist = Rcpp::Environment::global_env()["masslist"];
    params = Rcpp::Environment::global_env()["params"];
    isotope = Rcpp::Environment::global_env()["isotope"];
  }
};

// [[Rcpp::export]]
Rcpp::DataFrame FindFormula(Rcpp::DataFrame masslist_ = R_NilValue,
                            Rcpp::DataFrame params_ = R_NilValue,
                            Rcpp::DataFrame isotope_ = R_NilValue) {
  Rcpp::DataFrame masslist, params, isotope;
  my_defaults defaults;

  if (masslist_.size() == 0) {
    masslist = defaults.masslist;
  } else {
    masslist = masslist_;
  }
  // likewise for the others
  return masslist;
}

没有必要像我上面那样在 struct 中定义默认参数,您也可以调用,例如masslist = Rcpp::Environment::global_env()["masslist"]; 在你的函数中,但在我看来,前一种方法更有条理。无论如何,我强烈建议尽可能采用第一种方法。