17

这是一个与 Rcpp 转换相关的 Q。我希望将长 std::vector 转换为 Rcpp 矩阵对象,但想知道是否有简单的转换格式。自然地,您可以遍历每个元素并填充一个空的 Rcpp 矩阵,但这似乎容易出错并且如果可能有更方便的方法可能是不必要的。

我问的原因是我想在一些现有的 C++ 代码中使用 OpenMP,但是将元素直接存储在 OpenMP 循环中的 Rcpp 矩阵对象中似乎效果不佳(而加载 std::vector 对象并转换在 OpenMP 循环完成后到矩阵似乎是解决问题的一种不错的方法)。

任何帮助将不胜感激!

4

2 回答 2

22

扩展德克的答案;R 矩阵实际上只是具有dim属性集的向量

> x <- 1
> y <- as.matrix(x)
> .Internal( inspect(x) )
@7f81a6c80568 14 REALSXP g0c1 [MARK,NAM(2)] (len=1, tl=0) 1 ## data
> .Internal( inspect(y) )
@7f81a3ea86c8 14 REALSXP g0c1 [NAM(2),ATT] (len=1, tl=0) 1 ## data
ATTRIB:
  @7f81a3e68e08 02 LISTSXP g0c0 [] 
    TAG: @7f81a30013f8 01 SYMSXP g1c0 [MARK,LCK,gp=0x4000] "dim" (has value) 
    @7f81a3ea8668 13 INTSXP g0c1 [NAM(2)] (len=2, tl=0) 1,1

x请注意和的“数据”分量如何y只是REALSXPs,但是矩阵上有这个额外的dim分量。使用它,我们可以轻松地将 a 转换为NumericVector中的矩阵Rcpp

(注意:在下面的示例中,我SEXP在属性中使用,因此类型之间的转换是显式的):

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP vec_to_mat(SEXP x_) {
  std::vector<double> x = as< std::vector<double> >(x_);
  /* ... do something with x ... */
  NumericVector output = wrap(x);
  output.attr("dim") = Dimension(x.size(), 1);
  return output;
}

/*** R
m <- c(1, 2, 3)
vec_to_mat(m)
*/

给我

> m <- c(1, 2, 3)

> vec_to_mat(m)
     [,1]
[1,]    1
[2,]    2
[3,]    3

因此,您可以使用Dimension该类并将其分配给dim向量的属性,以在 Rcpp 中“手动”制作矩阵。

于 2013-11-08T19:23:38.217 回答
16

你选择了一个好的方法。在 OpenMP 上下文中,您必须远离单线程 R。这std::vector很好。

是的,我们有 from std::vectorto Rcpp::NumericVectorand的构造函数Rcpp::NumericMatrix(毕竟它只是一个具有维度属性的向量)以及Rcoo:Integer*变体,以及通常的as<>wrap转换器。

Rcpp 单元测试、Rcpp 示例,当然还有Rcpp Gallery站点上应该有很多示例。

编辑:这是一个过于简单的例子:

 R> cppFunction('NumericVector phil(int n) { std::vector<double> x(n);
 +              return wrap(x); }') 
 R> phil(4)  
 [1] 0 0 0 0    
 R>    
于 2013-11-08T16:52:57.580 回答