【问题标题】:how to modify values of a file-backed matrix in bigmemory rcpp如何在 bigmemory rcpp 中修改文件支持矩阵的值
【发布时间】:2017-11-12 21:49:19
【问题描述】:

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

下面是我写的 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;
      }
    }
  }
} 

【问题讨论】:

    标签: c++ rcpp r-bigmemory


    【解决方案1】:

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

    MatrixAccessor&lt;int&gt; 为您提供int 类型值的访问器。 R 中的任何数字都可以是 NA,但 C++ 中的 int 绝不是 NAN。优化编译器可以完全忽略std::isnan(x),其中x 的类型为int,就像您的情况一样。

    要解决此问题,您可以:

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

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

    【讨论】:

    • 非常感谢。这实际上是存在 NA 的位置的 int 值。我会尝试这样实现它。
    • 它可以在不使用外部标头甚至使用MatrixAccessor&lt;int&gt; 的情况下工作。因此接受了答案。
    【解决方案2】:

    bigmemory有一些检查NA的功能。

    只需在标题中添加#include &lt;bigmemory/isna.hpp&gt;。 并将std::isnan(mat[j][i]) 替换为isna(mat[j][i])

    【讨论】:

    • 我将实施您的建议,并以约翰的建议为基准。谢谢。
    • @MoisésExpósitoAlonso:我想看看那个基准测试的结果。
    • 这两种实现应该没有区别。唯一的区别是它已经由 bigmemory 的作者实现(对于charshortintegerdouble)。不应该重新发明轮子。
    猜你喜欢
    • 2020-03-03
    • 1970-01-01
    • 2018-01-27
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多