我将基于R的代码转换为基于Rcpp的代码。我的职责是:
NumericMatrix createMatrixOfLinkRatiosC(NumericMatrix matr, double threshold4Clean) {
int i,j;
NumericMatrix myMatr(matr.nrow(),matr.ncol());
myMatr=matr;
....;
}
我想处理对缺少threshold4Clean的函数的调用,但我没有找到该怎么办...将非常感谢任何帮助。
答案 0 :(得分:24)
R同时包含NaN
和NA
(实际上是一种特殊的NaN
)来表示缺失值。这一点很重要,因为有许多函数可以检查值是NaN
- y(NA
还是NaN
):
来自R / C API的函数的一些真值表(注意令人沮丧的缺乏一致性)
+---------------------+
| Function | NaN | NA |
+---------------------+
| ISNAN | t | t |
| R_IsNaN | t | f |
| ISNA | f | t |
| R_IsNA | f | t |
+---------------------+
和Rcpp:
+-------------------------+
| Function | NaN | NA |
+-------------------------+
| Rcpp::is_na | t | t |
| Rcpp::is_nan | t | f |
+-------------------------+
并从R解释器(注意:Rcpp尝试匹配此,而不是R / C API):
+---------------------+
| Function | NaN | NA |
+---------------------+
| is.na | t | t |
| is.nan | t | f |
+---------------------+
不幸的是,这是一个令人困惑的环境,但这应该会让你有所帮助。
答案 1 :(得分:7)
Rcpp和RcppArmadillo都有谓词来测试NA
,NaN
(R扩展名)和Inf
。
这是一个简短的RcppArmadillo示例:
#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)
***/
我们初始化一个零矩阵,并测试参数。如果它是有限的(即不是NA
或Inf
或NaN
),那么我们添加该值。如果你愿意,你也可以单独测试各种可能性。
这会产生所需的结果:没有第二个参数,默认值NA
适用,我们得到一个零矩阵。
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>
答案 2 :(得分:3)
我已经对此进行了测试,可以揭示一些可能性。
对于单个SEXP target
,我使用的Rcpp
选项是:
switch(TYPEOF(target)) {
case INTSXP:
return Rcpp::traits::is_na<INTSXP>(Rcpp::as<int>(target));
case REALSXP:
return Rcpp::traits::is_na<REALSXP>(Rcpp::as<double>(target));
case LGLSXP:
return Rcpp::traits::is_na<LGLSXP>(Rcpp::as<int>(target));
case CPLXSXP:
return Rcpp::traits::is_na<CPLXSXP>(Rcpp::as<Rcomplex>(target));
case STRSXP: {
Rcpp::StringVector vec(target);
return Rcpp::traits::is_na<STRSXP>(vec[0]);
}
}
如果您不想使用Rcpp
进行检查,请注意以下几点:
NA
(均存储为int
)等于int
的最小值(-2147483648)。double
,您可以直接使用Rcpp
uses,
即R_isnancpp
。
等效地,可以使用ISNAN
macro。double
方法检查实部和虚部。字符NA
很棘手,因为它是一个单例,所以地址很重要。
我个人一直在测试使用R字符进行操作而不存储std::string
以避免复制的方法,
即直接使用char*
。
我发现有效的方法是在.cpp
文件中声明此内容:
static const char *na_string_ptr = CHAR(Rf_asChar(NA_STRING));
,并且基于this answer,
为Rcpp::StringVector
或Rcpp::StringMatrix
x
做这样的事情:
Rcpp::CharacterVector one_string = Rcpp::as<Rcpp::CharacterVector>(x[i]);
char *ptr = (char *)(one_string[0]);
return ptr == na_string_ptr;
最后一个仍然使用Rcpp
,
但我可以将其用于一次初始设置,然后仅使用char
指针。
我敢肯定,有一种方法可以对R的API进行类似的处理,
但这是我尚未尝试过的东西。