Я использую пакет bigmemory R и Rcpp для обработки больших матриц (от 1 до 10 миллионов столбцов x 1000 строк). После того, как я прочитал целочисленную матрицу, состоящую из 0, 2 и NA, в матрицу большой памяти с обратным файлом в RI, я хотел бы изменить через C ++ все значения NA, чтобы сделать вменение средних значений для столбца или вменения произвольного значения (I покажи здесь последнее).
Ниже написана функция Rcpp, которая не работает. Я надеюсь, что это призвание BigNA(mybigmatrix@address)
изнутри R может найти элементы в матрице, которые являются NA, и изменить его значения непосредственно в файле поддержки.
Я думаю, что проблема может быть в оценке std::isnan(mat[j][i])
, Я проверил это, создав альтернативную функцию, которая подсчитывает значения NA с помощью аккумулятора и даже не учитывает ни одного NA. Но как только это решится, я также не уверен, что выражение mat[j][i] = 1
изменил бы значение в файле поддержки. Написание этих утверждений кажется мне интуитивно понятным, но я могу ошибаться.
Любая помощь / предложение будет очень цениться.
#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;
}
}
}
}
Проблема заключается в разнице между NA
в R и NAN
в C ++.
MatrixAccessor<int>
дает вам доступ к значениям типа int
, Любое число в R может быть NA
, но int
в C ++ никогда NAN
, Оптимизирующий компилятор может полностью игнорировать std::isnan(x)
где x
имеет тип int
, как в вашем случае.
Чтобы это исправить, вы можете:
MatrixAccessor<float>
(или же double
). Это подразумевает фактическое хранение другого типа данных.NA
элементы. Я думаю, вы найдете это INT_MIN
на С ++ (-2147483648). замещать isnan(x)
с x == INT_MIN
,Связанные с: Извлечение столбца с NA из объекта Bigmemory в Rcpp
пакет bigmemory имеет некоторые функции для проверки NA.
Просто добавьте заголовок с #include <bigmemory/isna.hpp>
,
И заменить std::isnan(mat[j][i])
от isna(mat[j][i])
,