2017-11-12 6 views
0

大きな行列(1〜1000万列×1000行)を扱うためにR bigmemoryパッケージとRcppを使用しています。いったん私が0、2、およびNAで構成されるインタジェクタ・マトリックスを、RIのファイル・バックされたビッグ・メモリ・マトリックスに読み込むと、C++を使ってすべてのNA値を変更して、カラムあたりの平均値または任意の値の帰属を転用したい後者をここに示す)。bigmemory rcppでファイルバッキングされた行列の値を変更する方法

以下は私が書いたRcpp関数であり、動作しません。私の望みは、R内からBigNA([email protected])を呼び出すと、NAsである行列内の要素を見つけ出し、バッキングファイルでその値を直接変更できることでした。

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; 
     } 
    } 
    } 
} 

答えて

1

問題は、C++におけるRでNANANの差から生じます。

MatrixAccessor<int>は、タイプintの値のアクセサーを提供します。 Rの任意の数はNAですが、C++のintは決してNANではありません。最適化コンパイラは、xintであるstd::isnan(x)を完全に無視することができます。この問題を解決するには

、あなたはどちらかの可能性:

  • 使用MatrixAccessor<float>(またはdouble)。これは、実際には異なるデータ型を格納することを意味します。
  • 実際にNA要素の値を確認してください。私はそれがINT_MIN C++(-2147483648)であると思います。 isnan(x)x == INT_MINに置き換えてください。

関連:Extracting a column with NA's from a bigmemory object in Rcpp

+0

ありがとうございます。これは、実際には、NAが存在する位置でのint値です。私はそのように実装しようとします。 –

+0

外部ヘッダを使わずに、MatrixAccessor を使っても動作します。こうして答えが受け入れられた。 –

1

パッケージbigmemoryは、NASをチェックするために、いくつかの機能があります。

#include <bigmemory/isna.hpp>というヘッダーを追加するだけです。 std::isnan(mat[j][i])isna(mat[j][i])に置き換えてください。

+0

あなたの提案を実装し、Johnの提案でベンチマークします。ありがとう。 –

+0

@MoisésExpósitoAlonso:私はそのベンチマークの結果を見たいと思います。 –

+0

2つの実装に違いはありません。唯一の違いは、** bigmemory **( 'char'、' short'、 'integer'と' double')の著者によって既に実装されていることです。そして、車輪を再構築してはいけません。 –

関連する問題