0

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

下面是我编写的 Rcpp 函数,它不起作用。我希望BigNA(mybigmatrix@address)从 R 内部调用可以在矩阵中找到 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;
      }
    }
  }
} 
4

2 回答 2

1

bigmemory具有一些检查 NA 的功能。

只需添加带有#include <bigmemory/isna.hpp>. 并替换std::isnan(mat[j][i])isna(mat[j][i]).

于 2017-11-13T11:02:44.133 回答
1

问题源于NAR 和NANC++ 之间的差异。

MatrixAccessor<int>为您提供 type 值的访问器int。R 中的任何数字都可以是NA,但intC++ 中的 a 绝不是NAN。优化编译器可以完全忽略std::isnan(x)wherex的 type int,就像你的情况一样。

要解决此问题,您可以:

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

相关:从 Rcpp 中的 bigmemory 对象中提取具有 NA 的列

于 2017-11-12T22:00:09.280 回答