Rcpp中的高效子集(相当于R“中的”命令)

时间:2012-06-26 11:12:25

标签: r if-statement syntactic-sugar rcpp which

在Rcpp中,有各种“Rcpp sugar”命令允许在代码中进行很好的矢量化操作。在下面的代码中,我移过数据框,将其分解为向量,然后使用“ifelse”和“sum”sugar命令计算x等于y或y + 1的行的平均值。一切似乎都正常。

只是想知道是否有比这更简洁的方式 - 例如相当于“which”命令,它给出满足特定条件的索引点?在Armadillo中似乎有一个可用作“find”的工具,但这意味着使用不兼容的对象类型(你不能使用“find”和“ifelse”在一起)。

在同一主题上,是否可以让“ifelse”接受复合逻辑条件?例如,在下面的示例中,indic的定义由两个“ifelse”命令组成,它显然会更清洁。任何想法都会非常感激。

期待听到您的回复:)

require(Rcpp)
require(inline)

set.seed(42)
df = data.frame(x = rpois(1000,3), y = rpois(1000,3), v = rnorm(1000),
                stringsAsFactors=FALSE)

myfunc1 = cxxfunction(
    signature(DF = "data.frame"),
    plugin = "Rcpp",
    body = '
            using namespace Rcpp;
            DataFrame df(DF);
            IntegerVector x = df["x"];
            IntegerVector y = df["y"];
            NumericVector v = df["v"];

            LogicalVector indic = ifelse(x==y,true,ifelse(x==y+1,true,false));
            double subsum = sum(ifelse(indic,v,0));
            int subsize = sum(indic);
            double mn = ((subsize>0) ? subsum/subsize : 0.0);

            return(Rcpp::List::create(_["subsize"] = subsize, 
                                      _["submean"] = mn
                                     ));
            '
            )

myfunc1(df)

### OUTPUT:
# 
# $subsize
# [1] 300
# 
# $submean
# [1] 0.1091555
# 

1 个答案:

答案 0 :(得分:3)

Rcpp(> = 0.10.0)在两个逻辑糖表达式之间实现 | 运算符。所以你可以这样做:

require( Rcpp )

cppFunction( code = '
List subsum( IntegerVector x, IntegerVector y, NumericVector v){
    using namespace Rcpp ;

    LogicalVector indic  = (x==y) | (x==y+1) ;
    int subsize          = sum(indic) ;
    double submean       = subsize == 0 ? 0.0 : sum(ifelse(indic,v,0)) / subsize ;

    return List::create( _["subsize"] = subsize, _["submean"] = submean ) ;
}
' )
subsum( rpois(1000,3), rpois(1000,3), rnorm(1000) )
# $subsize
# [1] 320
# 
# $submean
# [1] -0.05708866