Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rcpp function check if missing value

Tags:

r

rcpp

I'm converting R based code into Rcpp based code. The head of my function is:

NumericMatrix createMatrixOfLinkRatiosC(NumericMatrix matr, double threshold4Clean) {
int i,j; 
NumericMatrix myMatr(matr.nrow(),matr.ncol());
myMatr=matr;
....;

}

I want to handle call to the function where threshold4Clean is missing but I'm not finding how to do... Any help will be greatly appreciated.

like image 956
Giorgio Spedicato Avatar asked Oct 07 '14 16:10

Giorgio Spedicato


2 Answers

R has both NaN and NA (which is really a special kind of NaN) for representing missing values. This is important to know because there are many functions that check if a value is NaN-y (NA or NaN):

Some truth tables for functions from the R/C API (note the frustrating lack of consistency)

+---------------------+
| Function | NaN | NA |
+---------------------+
| ISNAN    |  t  | t  |
| R_IsNaN  |  t  | f  |
| ISNA     |  f  | t  |
| R_IsNA   |  f  | t  |
+---------------------+

and Rcpp:

+-------------------------+
| Function     | NaN | NA |
+-------------------------+
| Rcpp::is_na  |  t  | t  |
| Rcpp::is_nan |  t  | f  |
+-------------------------+

and from the R interpreter (note: Rcpp tries to match this, rather than the R/C API):

+---------------------+
| Function | NaN | NA |
+---------------------+
| is.na    |  t  | t  |
| is.nan   |  t  | f  |
+---------------------+

Unfortunately it's a confusing landscape, but this should empower you a bit.

like image 134
Kevin Ushey Avatar answered Nov 06 '22 04:11

Kevin Ushey


Both Rcpp and RcppArmadillo have predicates to test for NA, NaN (an R extension) and Inf.

Here is a short RcppArmadillo example:

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::mat foo(int n, double threshold=NA_REAL) {
  arma::mat M = arma::zeros<arma::mat>(n,n);
  if (arma::is_finite(threshold)) M = M + threshold;
  return M;
}

/*** R
foo(2)
foo(2, 3.1415)
***/

We initialize a matrix of zeros, and test for the argument. If it is finite (ie not NA or Inf or NaN), then we add that value. If you wanted to, you could test for the possibilities individually too.

This produces the desired result: without a second argument the default value of NA applies, and we get a matrix of zeros.

R> Rcpp::sourceCpp("/tmp/giorgio.cpp")

R> foo(2)
     [,1] [,2]
[1,]    0    0
[2,]    0    0

R> foo(2, 3.1415)
       [,1]   [,2]
[1,] 3.1415 3.1415
[2,] 3.1415 3.1415
R> 
like image 11
Dirk Eddelbuettel Avatar answered Nov 06 '22 05:11

Dirk Eddelbuettel