[Rcpp-devel] inconsistent is_na() vs. is.na()

Thomas Tse tommy_228_228 at yahoo.com.hk
Wed Oct 2 13:31:46 CEST 2013


Hi,

is_na() does not handles R's NaN correctly, for the below test.cpp:

#include <Rcpp.h>
using namespace Rcpp;
using namespace std;

// [[Rcpp::export]]
void test (NumericVector x)
{
  LogicalVector y1 = is_na(x);
  LogicalVector y2 = is_finite(x);
  LogicalVector y3 = is_infinite(x);
  LogicalVector y4 = is_nan(x);

  Rcpp::Rcout << "x= ";
  for(int i = 0; i < x.size(); i++) Rcpp::Rcout << x[i] << " ";
  Rcpp::Rcout << std::endl;

  Rcpp::Rcout << "is_na(x)= ";
  for(int i = 0; i < y1.size(); i++) Rcpp::Rcout << y1[i] << " ";
  Rcpp::Rcout << std::endl;

  Rcpp::Rcout << "is_finite(x)= ";
  for(int i = 0; i < y2.size(); i++) Rcpp::Rcout << y2[i] << " ";
  Rcpp::Rcout << std::endl;

  Rcpp::Rcout << "is_infinite(x)= ";
  for(int i = 0; i < y3.size(); i++) Rcpp::Rcout << y3[i] << " ";
  Rcpp::Rcout << std::endl;

  Rcpp::Rcout << "is_nan(x)= ";
  for(int i = 0; i < y4.size(); i++) Rcpp::Rcout << y4[i] << " ";
  Rcpp::Rcout << std::endl;
}



and the below codes in R, we see that is_na() in C++ does NOT match is.na() in R (in NaN case):

> sourceCpp('test.cpp');
> x <- c(1:3, NA, 4, Inf, -Inf, NaN);

> test(x);
x= 1 2 3 1.#QNAN 4 1.#INF -1.#INF -1.#IND
is_na(x)= 0 0 0 1 0 0 0 0
is_finite(x)= 1 1 1 0 1 0 0 0
is_infinite(x)= 0 0 0 0 0 1 1 0
is_nan(x)= 0 0 0 0 0 0 0 1
> is.na(x);       # !!! DIFFERENT when dealing with NaN
[1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE
> is.finite(x);   # same
[1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE FALSE
> is.infinite(x); # same
[1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE
> is.nan(x);      # same
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE


so, in .....\include\Rcpp\traits\is_na.h, we should modify like this:
template <>
inline bool is_na<REALSXP>( double x ){
//return R_IsNA(x) ;
return R_IsNA(x) || R_IsNaN(x);
}

template <>
inline bool is_na<CPLXSXP>( Rcomplex x ){
//return R_IsNA(x.r) || R_IsNA(x.i) ;
return R_IsNA(x.r) || R_IsNA(x.i) || R_IsNaN(x.r) || R_IsNaN(x.i);
}



is it possible to apply this change in next release of Rcpp ?

many thanks,
Thomas



More information about the Rcpp-devel mailing list