Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rcpp pass vector of length 0 (NULL) to cppfunction

Tags:

r

rcpp

I have a cppFunction with a vector ints as input, e.g:

library(Rcpp)
cppFunction('double test2(NumericVector ints) {
            return 42;
            }')

The output is correct if passing a vector of length at least 1:

> test2(1)
[1] 42
> test2(1:10)
[1] 42

For input of length 0 however I get:

> test2(c())
Error: not compatible with requested type

Is there any way to pass a vector of length 0 or larger to my function? I.e. my expected output is:

> test2_expectedoutput(c())
[1] 42

I know I could control for this in R by checking in R first and calling a different version of the function but would like to avoid this. I expect there is some easy solution out there since within cpp I could also have a NumericVector of length 0 if I understand correctly what NumericVector zero; does. The only related question I could find was this on how to return a NULL object from within a Rcpp function to R.

like image 231
mts Avatar asked Dec 10 '22 19:12

mts


1 Answers

A few months ago we added the ability to pass as Nullable<T> which may be what you want here.

Here is a simple example:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
bool checkNull(Nullable<NumericVector> x) {
  if (x.isNotNull()) {
    // do something
    NumericVector xx(x);
    Rcpp::Rcout << "Sum is " << sum(xx) << std::endl;
    return true;
  } else {
    // do nothing
    Rcpp::Rcout << "Nothing to see" << std::endl;
    return false;
  }
}

/*** R
checkNull(1:3)
checkNull(NULL)
*/

and its output:

R> sourceCpp("/tmp/null.cpp")

R> checkNull(1:3)
Sum is 6
[1] TRUE

R> checkNull(NULL)
Nothing to see
[1] FALSE
R> 

By being templated we respect the intended type but clearly differentiate between being there, and not.

like image 148
Dirk Eddelbuettel Avatar answered Jan 05 '23 00:01

Dirk Eddelbuettel