繁体   English   中英

在 Rcpp 中使用 sample()

[英]Using sample() from within Rcpp

我有一个包含概率的矩阵,四列中的每一列对应一个分数(从 0 到 4 的整数)。 我想使用该行中包含的概率作为采样权重为每一行采样一个分数。 在某些列不包含概率(取而代之的是 NA)的行中,抽样框架仅限于包含概率的列(及其相应的分数)(例如,对于具有 0.45、0.55、NA、NA 的行,0 或 1 将是采样)。 但是,我收到了这个错误(后面还有其他几个),那么我怎样才能让它工作呢?:

error: no matching function for call to 'as<Rcpp::IntegerVector>(Rcpp::Matrix<14>::Sub&)'
     score[i] = sample(scrs,1,true,as<IntegerVector>(probs));

现有答案表明 RcppArmadillo 是解决方案,但我也无法让它发挥作用。 如果我在 cppFunction 和score[i] = Rcpp::RcppArmadillo::sample(scrs,1,true,probs);之前添加: require(RcppArmadillo) ); 代替现有的 sample() 语句,我得到:

error: 'Rcpp::RcppArmadillo' has not been declared
     score[i] = Rcpp::RcppArmadillo::sample(scrs,1,true,probs);

或者,如果我还包括#include <RcppArmadilloExtensions/sample.h>在顶部,我得到:

fatal error: RcppArmadilloExtensions/sample.h: No such file or directory
   #include <RcppArmadilloExtensions/sample.h>

可重现的代码:

p.vals <- matrix(c(0.44892077,0.55107923,NA,NA,
                 0.37111195,0.62888805,NA,NA,
                 0.04461714,0.47764478,0.303590351,1.741477e-01,
                 0.91741642,0.07968127,0.002826406,7.589714e-05,
                 0.69330800,0.24355559,0.058340934,4.795468e-03,
                 0.43516823,0.43483784,0.120895859,9.098067e-03,
                 0.73680809,0.22595438,0.037237525,NA,
                 0.89569365,0.10142719,0.002879163,NA),nrow=8,ncol=4,byrow=TRUE)

step.vals <- c(1,1,3,3,3,3,2,2)

require(Rcpp)
cppFunction('IntegerVector scores_cpp(NumericMatrix p, IntegerVector steps){

  int prows = p.nrow();

  IntegerVector score(prows);
  
  for(int i=0;i<prows;i++){
    int step = steps[i];
    
    IntegerVector scrs = seq(0,step);
    
    int start = 0;
    int end = step;
    
    NumericMatrix::Sub probs = p(Range(i,i),Range(start,end));

    score[i] = sample(scrs,1,true,probs);
  }
  
  return score;
  
}')

test <- scores_cpp(p.vals,step.vals)
test

注意:每行的 step.vals 的值始终等于该行中包含概率的列数 -1。 所以将 step.values 传递给函数可能是多余的。

您可能会在这里拥有“以树换林”的时刻。 RcppArmadillo单元测试实际上提供了一个工作示例。 如果您查看源文件inst/tinytest/test_sample.R ,它有一个简单的

Rcpp::sourceCpp("cpp/sample.cpp")

那个文件 inst/tinytest/cpp/sample.cpp我们有标准

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

#include <RcppArmadilloExtensions/sample.h>

a) 告诉 R 查看RcppArmadillo头目录和 b) 包括采样器扩展。 这就是它的工作方式,并且已被证明可以工作近十年。

作为一个例子,我可以做(在我的$HOME包含git/rcpparmadillo的目录中)

> Rcpp::sourceCpp("git/rcpparmadillo/inst/tinytest/cpp/sample.cpp")
> set.seed(123)
> csample_integer(1:5, 10, TRUE, c(0.4, 0.3, 0.2, 0.05, 0.05))
 [1] 1 3 2 3 4 1 2 3 2 2
> 

后来的 Rcpp 添加的工作方式相同,但我发现使用 RcppArmadillo 处理矩阵的部分内容更具表现力和方便性。

编辑:对于安装了RcppArmadillo软件包的任何人来说更简单:

< library(Rcpp)
> sourceCpp(system.file("tinytest","cpp","sample.cpp", package="RcppArmadillo"))
> set.seed(123)
> csample_integer(1:5, 10, TRUE, c(0.4, 0.3, 0.2, 0.05, 0.05))
 [1] 1 3 2 3 4 1 2 3 2 2
> 

非常感谢您的指点。 我在索引矩阵时也遇到了一些问题,所以这部分也被改变了。 以下代码按预期工作(使用sourceCpp() ):

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

#include <RcppArmadilloExtensions/sample.h>

using namespace Rcpp;

// [[Rcpp::export]]

IntegerVector scores_cpp(NumericMatrix p, IntegerVector steps){
  
  int prows = p.nrow();
  
  IntegerVector score(prows);
  
  for(int i=0;i<prows;i++){
    int step = steps[i];
    
    IntegerVector scrs = seq(0,step);
    
    NumericMatrix probs = p(Range(i,i),Range(0,step));

    IntegerVector sc = RcppArmadillo::sample(scrs,1,true,probs);
    score[i] = sc[0];
  }
  
  return score;
  
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM