gpt4 book ai didi

rcpp - Rcpp向量子集的多态性

转载 作者:行者123 更新时间:2023-12-01 07:58:31 25 4
gpt4 key购买 nike

这是我想翻译成 c++ 以加快速度的一种 R 方法

setMethod("[[", signature=signature(x="ncdfFlowSet"),
definition=function(x, i, j, use.exprs = TRUE, ...)
{
#subset by j
if(!missing(j)){
if(is.character(j)){
j <- match(j, localChNames)
if(any(is.na(j)))
stop("subscript out of bounds")
}

fr@parameters <- fr@parameters[j, , drop = FALSE]
localChNames <- localChNames[j]
}

#other stuff

})

Kevin 在 vector subsetting 上的出色工作这个 j 子集

让我的生活更轻松
    // [[Rcpp::export]]
Rcpp::S4 readFrame(Rcpp::S4 x
, std::string sampleName
, Rcpp::RObject j_obj
, bool useExpr
)
{
Rcpp::Environment frEnv = x.slot("frames");
Rcpp::S4 frObj = frEnv.get(sampleName);
Rcpp::S4 fr = Rcpp::clone(frObj);

//get local channel names
Rcpp::StringVector colnames = x.slot("colnames");

Rcpp::StringVector ch_selected;
/*
* subset by j if applicable
*/
int j_type = j_obj.sexp_type();
//creating j index used for subsetting colnames and pdata
Rcpp::IntegerVector j_indx;

if(j_type == STRSXP)//when character vector
{
ch_selected = Rcpp::StringVector(j_obj.get__());
unsigned nCol = ch_selected.size();
j_indx = Rcpp::IntegerVector(nCol);
//match ch_selected to colnames
for(unsigned i = 0 ; i < nCol; i ++)
{
const Rcpp::internal::string_proxy<STRSXP> &thisCh = ch_selected(i);
Rcpp::StringVector::iterator match_id = std::find(colnames.begin(), colnames.end(), thisCh);
if(match_id == colnames.end()){
std::string strCh = Rcpp::as<std::string>(thisCh);
Rcpp::stop("j subscript out of bounds: " + strCh);
}else
{
j_indx(i) = match_id - colnames.begin();
}
}
}
else if(j_type == NILSXP)//j is set to NULL in R when not supplied
{
ch_selected = colnames;
}
else if(j_type == LGLSXP)
{
Rcpp::LogicalVector j_val(j_obj.get__());
ch_selected = colnames[j_val];
#to convert numeric indices to integer
}
else if(j_type == INTSXP)
{
Rcpp::IntegerVector j_val(j_obj.get__());
j_indx = j_val - 1; //convert to 0-based index
ch_selected = colnames[j_indx];
}
else if(j_type == REALSXP)
{
Rcpp::NumericVector j_val(j_obj.get__());
#to convert numeric indices to integer
}
else
Rcpp::stop("unsupported j expression!");
/*
* subset annotationDataFrame (a data frame)
*
*/
if(j_type != NILSXP)
{
Rcpp::S4 pheno = fr.slot("parameters");
Rcpp::DataFrame pData = pheno.slot("data");

Rcpp::CharacterVector pd_name = pData["name"];
Rcpp::CharacterVector pd_desc = pData["desc"];
Rcpp::NumericVector pd_range = pData["range"];
Rcpp::NumericVector pd_minRange = pData["minRange"];
Rcpp::NumericVector pd_maxRange = pData["maxRange"];

Rcpp::DataFrame plist = Rcpp::DataFrame::create(Rcpp::Named("name") = pd_name[j_indx]
,Rcpp::Named("desc") = pd_desc[j_indx]
,Rcpp::Named("range") = pd_range[j_indx]
,Rcpp::Named("minRange") = pd_minRange[j_indx]
,Rcpp::Named("maxRange") = pd_maxRange[j_indx]
);
pheno.slot("data") = plist;
}

然而,R 中的 j 索引通常允许不同类型的输入(characterlogical数字)。我想知道是否有相同类型的 polymorphic 机制(可能通过抽象向量指针/引用)以便 的冗余代码(仅由于 Rcpp::**Vector 的不同类型)以后可以避免data.frame上的[-subsetting

最佳答案

我们通常主张将逻辑分离为一个调度步骤和一个模板化功能步骤。因此,您应该能够通过以下方式解决您的问题:

#include <Rcpp.h>
using namespace Rcpp;

template <typename T>
SEXP readFrame(Rcpp::S4 x, std::string sampleName, T const& j, bool useExpr) {
// use the typed 'j' expression
}

// [[Rcpp::export(subset)]]
SEXP readFrame_dispatch(Rcpp::S4 x, std::string sampleName, SEXP j, bool useExpr)
switch (TYPEOF(j)) {
case INTSXP: return readFrame<IntegerVector>(x, sampleName, j, useExpr);
case REALSXP: return readFrame<NumericVector>(x, sampleName, j, useExpr);
case STRSXP: return readFrame<CharacterVector>(x, sampleName, j, useExpr);
case LGLSXP: return readFrame<LogicalVector>(x, sampleName, j, useExpr);
default: stop("Unsupported SEXP type");
}
return R_NilValue;
}

Rcpp 的设计目标之一是出于速度原因尽可能避免运行时多态性——几乎所有多态性都是静态完成的,理想情况下运行时查找应该只发生一次(除了偶尔我们被迫回调到 R 的一些例程)。

调度代码有点丑陋和机械,但允许这种“风格”的编程。如果'dispatch' 也与'implementation' 分开,代码的可读性也会更高,因为您可以在一个位置隐藏dispatch 的丑陋。

我确实想知道是否有一些宏魔法可以减少这种形式的调度代码中的代码重复...

关于rcpp - Rcpp向量子集的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25254025/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com