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)
正在(大概)另一个名为 masslist
的 DataFrame
对象上调用 DataFrame
class 的构造函数/复制构造函数,但这不是你想要的,而且它无论如何都不会编译。您的函数签名(广义上讲)需要更像
ReturnType function_name(ParamType1 param1, ParamType2 param2, ...)
或者,使用默认参数,
ReturnType function_name(ParamType1 param1 = p1, ParamType2 param2 = p2, ...)
其中 p1
和 p2
是实际值,不是变量。
在你的情况下,我真的认为编写一个 没有 具有默认参数的 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"];
在你的函数中,但在我看来,前一种方法更有条理。无论如何,我强烈建议尽可能采用第一种方法。
使用数据帧(来自 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)
正在(大概)另一个名为 masslist
的 DataFrame
对象上调用 DataFrame
class 的构造函数/复制构造函数,但这不是你想要的,而且它无论如何都不会编译。您的函数签名(广义上讲)需要更像
ReturnType function_name(ParamType1 param1, ParamType2 param2, ...)
或者,使用默认参数,
ReturnType function_name(ParamType1 param1 = p1, ParamType2 param2 = p2, ...)
其中 p1
和 p2
是实际值,不是变量。
在你的情况下,我真的认为编写一个 没有 具有默认参数的 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"];
在你的函数中,但在我看来,前一种方法更有条理。无论如何,我强烈建议尽可能采用第一种方法。