Rcpp中的有效子设置(相当于R“which”命令)

时间:2022-05-04 21:24:35

In Rcpp, there are various "Rcpp sugar" commands that permit nice vectorised operations in the code. In the code below I move across a data frame, break it into vectors, then use the "ifelse" and "sum" sugar commands to compute the mean of v over the rows where x equals either y or y+1. All seems to work correctly.

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

Just wondering if there is a neater way than this - e.g. an equivalent of the "which" command that gives index points satisfying a particular condition? There seems to be a facility available as "find" in Armadillo but that means using incompatible object types (you can't use "find" and "ifelse" together).

只是想知道是否有比这更整洁的方法—例如,给出满足特定条件的索引点的“which”命令的等效方法?Armadillo中似乎有一个“查找”工具,但这意味着使用不兼容的对象类型(不能同时使用“查找”和“ifelse”)。

On the same topic, is it possible to get "ifelse" to accept a compound logical condition? In the example below, for instance, the definition of indic is formed of two "ifelse" commands, and it would obviously be cleaner as one. Any thoughts would be much appreciated.

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

Look forward to hearing your responses :)

期待听到你的回应:)

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 个解决方案

#1


3  

Rcpp (>= 0.10.0) implements the | operator between two logical sugar expressions. So you can do:

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

#1


3  

Rcpp (>= 0.10.0) implements the | operator between two logical sugar expressions. So you can do:

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