如何修改bigmemory中的文件支持矩阵的值rcpp

时间:2017-11-12 21:49:20

标签: c++ rcpp r-bigmemory

我正在使用R bigmemory包和Rcpp来处理大矩阵(1到10百万列x 1000行)。一旦我将包含0,2和NA的整数矩阵读入RI中的文件备份大记忆矩阵,就想通过C ++修改所有NA值,以便对每列的平均值进行插补或任意值插补(I在这里显示后者)。

以下是我编写的Rcpp函数,但不起作用。我希望从R中调用BigNA(mybigmatrix@address)可以在矩阵中找到作为NA的元素,并直接在后备文件中修改其值。

我认为问题可能出在std::isnan(mat[j][i])的评估中。我通过创建一个替代函数来检查这一点,该函数使用累加器计算NA值,并且实际上没有计算任何NA。但是一旦解决了这个问题,我也不确定表达式mat[j][i] = 1是否会修改后备文件中的值。写这些陈述对于我来说具有R背景感觉很直观,但可能是错误的。

非常感谢任何帮助/建议。

#include <stdio.h>
#include <Rcpp.h>
#include <bigmemory/MatrixAccessor.hpp>
#include <numeric>
// [[Rcpp::depends(BH, bigmemory)]]
// [[Rcpp::depends(Rcpp)]]


// [[Rcpp::export]]
void BigNA(SEXP pBigMat) {
  /*
  * Imputation of "NA" values for "1" in a big 0, 2 NA matrix.
  */

  // Create the external bigmatrix pointer and iniciate matrix accessor
  XPtr<BigMatrix> xpMat(pBigMat);
  MatrixAccessor<int> mat = (*xpMat);

  // Iterater over the elements in a matrix and when NA is found, substitute for "1"
  for(int i=0; i< xpMat->ncol(); i++){
    for(int j=0; j< xpMat->nrow(); j++){
      if(std::isnan(mat[j][i])){ 
        mat[j][i] = 1;
      }
    }
  }
} 

2 个答案:

答案 0 :(得分:1)

问题源于R中NA与C ++中NAN之间的差异。

MatrixAccessor<int>为您提供了int类型值的访问者。 R中的任何数字都可以是NA,但C ++中的int永远不会NAN。优化编译器可以完全忽略std::isnan(x) x类型为int的{​​{1}},就像您的情况一样。

要解决此问题,您可以:

  • 使用MatrixAccessor<float>(或double)。这意味着实际存储不同的数据类型。
  • 检查您为NA元素实际获得的值。我想你会发现它在C ++中是INT_MIN(-2147483648)。将isnan(x)替换为x == INT_MIN

相关:Extracting a column with NA's from a bigmemory object in Rcpp

答案 1 :(得分:1)

bigmemory 有一些检查NA的功能。

只需添加#include <bigmemory/isna.hpp>标题即可。 并将std::isnan(mat[j][i])替换为isna(mat[j][i])