使用Rcpp处理NA值

时间:2019-06-11 20:04:19

标签: r rcpp na

我正在测试一段代码,如下所示:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix testOutMat(const int& ncols, const int& nrows, const NumericVector& col_prob){

  //Store row and column positions
  NumericVector col_pos = no_init(nrows);
  NumericVector row_pos = no_init(nrows);

  int row_val;
  int nz_counter=0;
  for(int j=0; j<ncols; ++j){ 
    for(int i=0; i<nrows; ++i){
      row_val = R::rbinom(1,col_prob[j]);
      Rcout << "i,j: " << i << "," << j << std::endl;
      Rcout << "val: " << row_val << std::endl;
      if(row_val==1){ //if (i,j)th entry is a 1, save location
        row_pos[i] = i;
        col_pos[i] = j;
        nz_counter += 1;
      } else{ //assign as NA
        row_pos[i] = NA_REAL;
        col_pos[i] = NA_REAL;
      }
      Rcout << "row_pos[i]: " << row_pos[i] << std::endl;
      Rcout << "col_pos[i]: " << col_pos[i] << std::endl;
      Rcout << "num non-zeros: " << nz_counter << std::endl;
    }
  }

  NumericMatrix out = no_init(nz_counter,2);

  Rcout << "Printing output matrix" << std::endl;
  for(int i=0; i<nz_counter; ++i){
    if(!Rcpp::NumericVector::is_na(row_pos[i])){ 
      out(i,0) = row_pos[i];
      out(i,1) = col_pos[i];
    }
    Rcout << "row_pos[i]: " << row_pos[i] << std::endl;
    Rcout << "col_pos[i]: " << col_pos[i] << std::endl; 
  }

  return out;
}

/*** R
set.seed(1)
res <- testOutMat(ncols=5,nrows=5,col_prob = runif(20, 0.1, 0.2))
*/

从输出中,我得到条目(i,j)={(0,0),(3,1)}不为零,因此res应该是一个2x2矩阵,其中第一行是0 0,{ {1}}。但是,我得到了非常不同的东西:

3 1

我怀疑这是由于我处理 [,1] [,2] [1,] 64 1024 [2,] 1 4 的方式引起的。该函数的总体目标是为非零元素生成行索引和列索引(由对NA的调用生成)。

我已经尝试调试了一段时间,但似乎无法解决问题。

1 个答案:

答案 0 :(得分:2)

这里的问题是,您一次又一次(openssl pkcs12 -export -in /tmp/MyCert.crt -inkey /tmp/MyKey.key -out /tmp/MyP12.p12 -name alias -passin pass: -passout pass: 次)重复row_poscol_pos,而没有任何跟踪先前结果的方法。加上您ncols的使用,这就是导致您看到最终结果的原因。我们可以稍微更改一下代码,以确保no_init()row_pos不会被覆盖:

col_pos

结果:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
IntegerMatrix testOutMat(const int ncols, const int nrows,
                         const NumericVector& col_prob) {

    IntegerMatrix binomial_deviates(nrows, ncols);
    IntegerVector row_positions;
    IntegerVector col_positions;
    int nz_counter = 0;

    for ( int j = 0; j < ncols; ++j ) {
        binomial_deviates(_, j) = rbinom(nrows, 1, col_prob[j]);
        for ( int i = 0; i < nrows; ++i ) {
            if ( binomial_deviates(i, j) == 1 ) {
                row_positions.push_back(i);
                col_positions.push_back(j);
                nz_counter += 1;
            }
        }
    }

    IntegerMatrix out(nz_counter, 2);

    for ( int i = 0; i < nz_counter; ++i ) {
        out(i, 0) = row_positions[i];
        out(i, 1) = col_positions[i];
    }

    return out;
}

/*** R
set.seed(1)
res <- testOutMat(ncols=5,nrows=5,col_prob = runif(20, 0.1, 0.2))
*/