I wish to check that an Rcpp IntegerVector provided to a C++ function does not contain NA
values.
Following another answer, I have written the below:
IntegerMatrix stop_if_na(const IntegerVector I) {
if (Rcpp::is_true(Rcpp::any(Rcpp::IntegerVector::is_na(I)))) {
Rcpp::stop("`I` contains NA values");
}
But I see a compilation error:
note: candidate: 'template<bool NA, class T> bool Rcpp::is_na(const Rcpp::sugar::SingleLogicalResult<NA, T>&)'
38 | inline bool is_na( const Rcpp::sugar::SingleLogicalResult<NA,T>& x){
| ^~~~~
note: template argument deduction/substitution failed:
<file>.cpp:22:48 note: 'const IntegerVector' {aka 'const Rcpp::Vector<13, Rcpp::PreserveStorage>'} is not derived from 'const Rcpp::sugar::SingleLogicalResult<NA, T>'
22 | if (Rcpp::is_true(Rcpp::any(Rcpp::is_na(I)))) {
| ^
When I remove IntegerVector::
(as suggested by user20650 and Dirk Eddelbuettel) I see
error: matching function for call to 'is_na(const IntegerVector&)
20 | if (Rcpp::is_true(Rcpp::any(Rcpp::is_na(I)
|
template argument deduction/substitution failed:
<file>.cpp:20:48:note: 'const IntegerVector{aka 'const note: ndidate: 'template<bool NA, class T> bool Rcpp::is_na(const Rcpp::sugar::SingleLogicalResult<NA, T>&)
38 | inline bool is_nast Rcpp::sugar::SingleLogicalResult<NA,T>& x){
| ^~~~~
note: template argument deduction/substitution failed:
<file>.cpp:20:48:note: 'const IntegerVector{aka 'const Rcpp::Vector<13, Rcpp::PreserveStorage> is not derived from 'const Rcpp::sugar::SingleLogicalResult<NA, T>
20 | if (Rcpp::is_true(Rcpp::any(Rcpp::is_na(I)
| ^
(As the C++ function is exported from a package, I can't rely on the calling R function to perform this test.)
sessionInfo()
outputR Under development (unstable) (2022-07-19 r82607 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)
Matrix products: default
locale:
[1] LC_COLLATE=English_United Kingdom.utf8 LC_CTYPE=English_United Kingdom.utf8
[3] LC_MONETARY=English_United Kingdom.utf8 LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.utf8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] htmlwidgets_1.5.4 compiler_4.3.0 microbenchmark_1.4.9 magrittr_2.0.3
[5] fastmap_1.1.0 cli_3.3.0 profvis_0.3.7 tools_4.3.0
[9] htmltools_0.5.3 rstudioapi_0.13 stringi_1.7.8 stringr_1.4.0
[13] digest_0.6.29 rlang_1.0.4
packageVersion("Rcpp")
= 1.0.9
This is so core a feature that we had it more or less since day one, and I am a little surprised that you did not come across the very early Rcpp Gallery posts Working with Missing Values by Hadley from Dec 2012.
Note that the more interesting features are 'Sugar' functions:
> Rcpp::cppFunction("LogicalVector foo(NumericVector x) {return is_finite(x);}")
> foo(c(1.0, Inf, -Inf, NA, NaN, 42))
[1] TRUE FALSE FALSE FALSE FALSE TRUE
>
There are a few related predicates you may want to look into.
Your suggested function also works if you just remove the ::IntegerVector
in the call:
> Rcpp::cppFunction("void stop_if_na(const IntegerVector IV) {
+ if (Rcpp::is_true(Rcpp::any(Rcpp::is_na(IV)))) {
+ Rcpp::stop(\"`I` contains NA values\");
+ }
+ }")
> stop_if_na(1:5)
> stop_if_na(c(1:5, NA, 7:9))
Error: `I` contains NA values
>
For ease of re-use my code snippet follows.
Rcpp::cppFunction("LogicalVector foo(NumericVector x) { return is_finite(x); }")
foo(c(1.0, Inf, -Inf, NA, NaN, 42))
Rcpp::cppFunction("void stop_if_na(const IntegerVector IV) {
if (Rcpp::is_true(Rcpp::any(Rcpp::is_na(IV)))) {
Rcpp::stop(\"`I` contains NA values\");
}
}")
stop_if_na(1:5)
stop_if_na(c(1:5, NA, 7:9))