//[[Rcpp::export]]
int Class_data(SEXP data) {
/*
return 0 if class of data is matrix
else return -1
*/
}
How to determine the class of data
in the above case? If data
belongs to matrix
class return 0 else return -1.
//[[Rcpp::export]]
int Class_data(SEXP data) {
/*
return 0 if class of data is matrix
else return -1
*/
}
How to determine the class of data
in the above case? If data
belongs to matrix
class return 0 else return -1.
Depending on what type of object you are checking for, there may be a predefined Rf_isWhatever
macro, or you may need to use the Rf_inherits(object, "Whatever")
macro, both defined in the R source code, and available through the Rcpp header. For example,
#include <Rcpp.h>
// [[Rcpp::export]]
int is_matrix(SEXP data) {
return Rf_isMatrix(data) ? 0 : -1;
}
// [[Rcpp::export]]
int is_data_frame(SEXP x) {
return Rf_inherits(x, "data.frame") ? 0 : -1;
}
/*** R
is_matrix(matrix(1:6, 2))
#[1] 0
is_matrix(data.frame(1:5))
#[1] -1
is_data_frame(data.frame(1:5))
#[1] 0
is_data_frame(matrix(1:6, 2))
#[1] -1
*/
For reference, you can check the source code to see what is available.
Normally, you would know in advance what type the object is when working with Rcpp as you would specify:
//[[Rcpp::export]]
int Class_data(Rcpp::NumericMatrix) {
// code to reduce return to int
return 1;
}
Of course, there are exceptions when working with different element types (e.g. logical vs. character vs. numeric) and having one call function. I've included an example of this at the end.
Though, in the case when you do not, the best to do is use isMatrix
in R's vocab:
INLINE_FUN Rboolean isMatrix(SEXP s)
{
SEXP t;
if (isVector(s)) {
t = getAttrib(s, R_DimSymbol);
/* You are not supposed to be able to assign a non-integer dim,
although this might be possible by misuse of ATTRIB. */
if (TYPEOF(t) == INTSXP && LENGTH(t) == 2)
return TRUE;
}
return FALSE;
}
To handle a larger amount of objects (logical, character, etc..), you want an internal switch given in R's do_is()
function.
That may be a bit too big though and you may want help in dispatching different object types. To do so, see this example:
#include <Rcpp.h>
// Create a template generic (look up C++ templates)
template <int RTYPE>
int count_me(Vector<RTYPE> v){
return v.size() ; // Just want to show it can return sizes of different array types
}
// [[Rcpp::export]]
int fake_switch(SEXP x){
// customize with different functions
// Or, just pass different types into the template.
switch( TYPEOF(x) ){
case INTSXP: return count_me<INTSXP>(x); // integers
case REALSXP: return count_me<REALSXP>(x); // numeric
case STRSXP: return count_me<STRSXP>(x); // strings
default: Rcpp::stop("type not handled"); // no support for obj
}
return -1; // should never be trigger but here to make the compiler happy
}