使用数据帧(来自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的新手,所以我很感激任何了解数据框架的人。
答案 0 :(得分:2)
您的代码中有一些值得指出的语法问题。首先,NULL
有一个非常 different meaning in C/C++而不是R - 不要像你上面那样使用它。您可以在Rcpp代码中使用R_NilValue
来代表R&#39 {s} NULL
。此外,您的函数参数未正确声明。从语法上讲,这句话 -
Rcpp::DataFrame(masslist)
正在调用(大概)另一个名为DataFrame
的{{1}}对象的DataFrame
类的构造函数/复制构造函数,但这不是你想要的,它不会无论如何编译。您的功能签名(广义上讲)需要更像
masslist
或者,使用默认参数
ReturnType function_name(ParamType1 param1, ParamType2 param2, ...)
其中ReturnType function_name(ParamType1 param1 = p1, ParamType2 param2 = p2, ...)
和p1
是实际值,而不是变量。
在你的情况下,我真的认为编写不具有默认参数的Rcpp函数并从R中指定默认值的简单包装函数调用它更简单。例如,
p2
但是,如果坚持从C ++处理此问题,您可以采取相应的措施:
#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
*/
没有必要像我上面那样在#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
在你的职能范围内,但前一种方法感觉IMO更有条理。无论如何,如果可能的话,我强烈建议采用第一种方法。