2017-11-12 28 views
0

큰 행렬 (1에서 10 백만 열 x 1000 행)을 처리하기 위해 R bigmemory 패키지와 Rcpp를 사용하고 있습니다. 일단 RI에서 filebacked bigmemory 행렬에 0, 2 및 NA로 구성된 interger 행렬을 읽으려면 C++을 통해 모든 NA 값을 수정하여 컬럼 당 평균 값 또는 임의 값 대체 (imputation)를 수행하고 싶습니다. 여기에 후자 표시).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의 NA 간의 차이 NAN 유래.

MatrixAccessor<int>int 유형의 값에 대한 접근자를 제공합니다. R의 모든 숫자는 NA 일 수 있지만 C++의 int은 결코 NAN이 아닙니다. 최적화 컴파일러는 xint 인 경우 std::isnan(x)을 완전히 무시할 수 있습니다.

는이 문제를 해결하려면, 당신은 할 수 중 하나

  • 사용 MatrixAccessor<float> (또는 double). 이는 실제로 다른 데이터 유형을 저장하는 것을 의미합니다.
  • 실제로 NA 요소에 대한 값을 확인하십시오. C++ (-2147483648)에서 INT_MIN이라는 것을 알게 될 것입니다. isnan(x)x == INT_MIN으로 바꿉니다.

관련 : Extracting a column with NA's from a bigmemory object in Rcpp

+0

고맙습니다. 이것은 실제로 NA가있는 위치의 int 값입니다. 내가 그런 식으로 구현하려고 할 것입니다. –

+0

외부 헤더를 사용하지 않고 'MatrixAccessor '을 사용해도 작동합니다. 따라서 대답을 받아 들였다. –

1

패키지는 bigmemory 일부 기능의 NA를 확인할 수 있습니다.

#include <bigmemory/isna.hpp>과 함께 헤더를 추가하기 만하면됩니다. std::isnan(mat[j][i])isna(mat[j][i])으로 바꿉니다.

+0

나는 당신의 제안을 구현하고 그것을 John의 제안으로 벤치마킹 할 것입니다. 감사. –

+0

@ MoisésExpósitoAlonso : 그 벤치 마크 결과를보고 싶습니다. –

+0

두 가지 구현간에 차이가 없어야합니다. 유일한 차이점은 ** bigmemory ** ('char','short','integer'와'double')의 저자가 이미 구현했다는 것입니다. 그리고 바퀴를 재발명해서는 안됩니다. –