Search code examples
rcpp

Setting a `NULL` default for a parameter in Rcpp function


I want to set the default value of a parameter to NULL in an Rcpp function and do some calculation based on the parameter if the parameter is not NULL. An example of such a code would be

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int test_null(Nullable<DataFrame> p1 = R_NilValue){

  if(p1.isNull()){
    NumericMatrix T(2,2);
    Rcout << T << std::endl;
  }
    else{
    NumericMatrix T(p1.nrow());
    Rcout << T << std::endl;
  }
  return (42);
}

However, I am not able to compile this function and am getting an error message

error: no member named 'nrow' in 'Rcpp::Nullable<Rcpp::DataFrame_Impl<PreserveStorage> >'

which tells me that there is no nrow defined for a Nullable DataFrame. Is there any other way to do implement a default NULL value for a parameter (i.e., a DataFrame) in Rcpp so that I can calculate other properties (no. or rows, columns etc.) of the DataFrame when it is not NULL.

Any help would be greatly appreciated!

Thanks you!

SN248


Solution

  • You were very close. You missed one instantiation: a Nullable<> is not yet the same as its template type---we need to create an object first.

    So here is your code with corrected whitespace ;-) and the missing line plus a test invocation of each case:

    #include <Rcpp.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    int test_null(Nullable<DataFrame> p1 = R_NilValue){
    
      if (p1.isNull()) {
        NumericMatrix T(2,2);
        Rcout << T << std::endl;
      } else {
        DataFrame S(p1);
        NumericMatrix T(S.nrow());
        Rcout << T << std::endl;
      }
      return (42);
    }
    
    /*** R
    test_null(NULL)
    test_null(data.frame(a=1:3, b=letters[1:3]))
    */
    

    For which I get the expected result:

    R> Rcpp::sourceCpp("~/git/stackoverflow/61701367/answer.cpp")
    
    R> test_null(NULL)
    0.00000 0.00000
    0.00000 0.00000
    
    [1] 42
    
    R> test_null(data.frame(a=1:3, b=letters[1:3]))
    0.00000 0.00000 0.00000
    0.00000 0.00000 0.00000
    0.00000 0.00000 0.00000
    
    [1] 42
    R>