Rcpp:将SEXP转换为float / double

时间:2018-03-01 18:14:26

标签: r floating-point type-conversion double rcpp

SEXP callFunction1(List network, List words, Function testWordContinuity){
  SEXP res = testWordContinuity(network, words);
  return res;
}

for(int i=0; i<(n_epochs); i++){
  NumericVector outputMatchTracker = history["output.match.tracker"];
  outputMatchTracker[i] = callFunction1(network, words, testWordContinuity);
}

R中的testWordContinuity函数调用R中的另一个返回单个数字变量的函数

我所做的一切都是使用for循环替换向量中的值。 for循环开始后的第一行是将outputMatchTracker分配给零向量(history [&#34; output.match.tracker&#34;]),这样我就可以遍历零。

错误:&#34;无法转换&#39; SEXP&#39; to&#39; Rcpp :: traits :: storage_type&lt; 14&gt; :: type {aka double}&#39;在任务&#34;发生在上面for循环的最后一行。

有没有办法将res从SEXP转换为float或double?

我意识到这里有一个类似的问题: Rcpp cannot convert ‘SEXP {aka SEXPREC*}’ to ‘double’ in initialization但是这个问题通过使用Rcpp糖函数而不是R函数来解决,以避免将SEXP转换为double。

如果没有办法从SEXP转换为float或double,除了在Rcpp中编写R函数之外,还有一种解决这个问题的常用方法吗?

如有必要,很高兴提供更多信息,

谢谢。

编辑:

最小可重复示例:

在Rcpp中:

// [[Rcpp::export]]
SEXP callFunction(Function func){
  SEXP res = func();
  return(res);
}

// [[Rcpp::export]]
NumericVector func1(Function func){
  for(int i=0; i<10; i++){
    NumericVector vect(10);
    vect[i] = callFunction(func);
  }
  return(vect);
}

在获取此代码后,将显示上面指定的错误。

2 个答案:

答案 0 :(得分:0)

我相信你应该使用REAL宏,它返回一个指向double数组开头的指针。有关示例,请参阅https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Attributes

答案 1 :(得分:0)

作为Simon Byrne's answer的扩展-我知道有2种方法可以实现此目的:

  1. 请记住,R中的标量实际上始终是长度为1的向量。因此,将R SEXP对象转换为RCPP NumericVector,并使用索引(方括号)表示法引用第一个元素:
double callFunction1(List network, List words, Function testWordContinuity){
  SEXP res = testWordContinuity(network, words);
  NumericVector dblVec(res)
  return dblVec[0];
}
  1. 使用REAL宏并取消引用指针(指向第一个元素)。与方法1(未经测试)相比,这可能是微优化,但是瓶颈几乎可以肯定是testWordContinuity R函数。 asReal C库中还有一个<Rinternals.h>函数,但是考虑到REAL头文件中包含<Rcpp.h>宏,这似乎增加了不必要的复杂性包括<Rinternals.h>
double callFunction1(List network, List words, Function testWordContinuity){
  SEXP res = testWordContinuity(network, words);
  return *REAL(res);
}