Ich versuche eine Funktion zu erstellen, die eine Spalte aus einem big.matrix-Objekt in Rcpp extrahiert (damit sie in cpp analysiert werden kann, bevor die Ergebnisse auf R gebracht werden) , aber ich kann nicht herausfinden, wie man NA's erkennt (sie werden jetzt als -2147483648 dargestellt - wie in meinem Minimalbeispiel unten gezeigt). Es wäre noch besser, wenn ich direkt von Rcpp auf die Funktion GetMatrixCols (src/bigmemory.cpp) zugreifen könnte, aber ich habe noch einen Weg gefunden, dies zu tun.Eine Spalte mit NAs aus einem Bigmemory-Objekt in Rcpp extrahieren
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>
#include <bigmemory/isna.hpp>
using namespace Rcpp;
//Logic for extracting column from a Big Matrix object
template <typename T>
NumericVector GetColumn_logic(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat, int cn) {
NumericVector nv(pMat->nrow());
for(int i = 0; i < pMat->nrow(); i++) {
if(isna(mat[cn][i])) {
nv[i] = NA_INTEGER;
} else {
nv[i] = mat[cn][i];
}
}
return nv;
}
//' Extract Column from a Big Matrix.
//'
//' @param pBigMat A bigmemory object address.
//' @param colNum Column Number to extract. Indexing starts from zero.
//' @export
// [[Rcpp::export]]
NumericVector GetColumn(SEXP pBigMat, int colNum) {
XPtr<BigMatrix> xpMat(pBigMat);
switch(xpMat->matrix_type()) {
case 1: return GetColumn_logic(xpMat, MatrixAccessor<char>(*xpMat), colNum);
case 2: return GetColumn_logic(xpMat, MatrixAccessor<short>(*xpMat), colNum);
case 4: return GetColumn_logic(xpMat, MatrixAccessor<int>(*xpMat), colNum);
case 6: return GetColumn_logic(xpMat, MatrixAccessor<float>(*xpMat), colNum);
case 8: return GetColumn_logic(xpMat, MatrixAccessor<double>(*xpMat), colNum);
default: throw Rcpp::exception("Unknown type detected for big.matrix object!");
}
}
/*** R
bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
bigmemory:::CGetType([email protected])
bigmemory:::GetCols.bm(bm, 3)
GetColumn([email protected], 2)
*/
Danke Dirk, schätze wirklich all deine Arbeit an Rcpp. Obwohl dies die richtige Antwort liefert, denke ich immer noch, dass es "einfacher" wäre, wenn ich die GetMatrixCols-Funktion aufrufen könnte - nicht nur, weil sie genau diese Operation ausführt, sondern weil ich ähnliche Bedürfnisse in anderen Projekten habe -> * * Die Notwendigkeit, Rcpp Exportierte Funktionen in meinem eigenen Rcpp-Code aufzurufen.** Ich habe eine Header-Datei erstellt, die 'SEXP GetMatrixCols (SEXP bigMatAddr, SEXP col) enthält; und habe eine neue Version von bigmemory erstellt, aber wenn ich SourceCpp: ed:' Fehler in dyn.load' .. Irgendwelche Ideen, wie man vorgeht oder Mache ich etwas wirklich dummes? – samssan
Zu 1): Ich denke, das ist ein Fehler. Dann kann das Binärmuster einer NA die erzwungene Kopie von "double" zu "int" nicht überleben. Erstellen Sie einfach "double" bei der Eingabe. Re 2) und Fettschrift. Keine Ahnung, wovon du sprichst. * Jedes * Paket, das Rcpp-Attribute verwendet, macht das, siehe die Rcpp-Attribut-Vignette für Details. Re 3) Ich vermute, Sie haben einen Hang-up auf Paket-Build. Neue Frage oder Post zu rcpp-devel? –
Weiß nicht, ob das noch klarer ist, aber ich werde es versuchen. Es gibt eine cpp-Funktion in OtherPackage und sie ist nicht in den Header-Dateien dieses Pakets definiert. Ich muss diese Funktion in MyPackage auf cpp-Ebene verwenden. Ich habe eine ähnliche Frage hier gefunden [link] (http://stackoverflow.com/questions/27079811/how-do-i-share-c-functions-in-rcpp-based-libraries-between-r-packages?rq= 1). Ich versuche das vorerst zu verfolgen. Vielen Dank! – samssan