简体   繁体   English

将std :: vector转换为Rcpp矩阵

[英]Convert std::vector to Rcpp matrix

This is an Rcpp conversion related Q. I'm looking to convert a long std::vector into a Rcpp matrix object, but want to know if there is an easy conversion format. 这是一个与Rcpp转换相关的Q.我正在寻找将长std :: vector转换为Rcpp矩阵对象,但想知道是否有一个简单的转换格式。 Naturally, you could loop over each element and fill an empty Rcpp matrix, but this seems error prone and possibly needless if a more convenient approach is possible. 当然,你可以遍历每个元素并填充一个空的Rcpp矩阵,但这似乎容易出错,如果可以采用更方便的方法,则可能是不必要的。

The reason I'm asking is I would like to utilize OpenMP in some existing C++ code, but storing element in the Rcpp matrix object directly in an OpenMP loop doesn't appear to work well (whereas loading a std::vector object and converting to a matrix after the OpenMP loop is complete seems to be a decent approach to the problem). 我问的原因是我想在一些现有的C ++代码中使用OpenMP,但是直接在OpenMP循环中将元素存储在Rcpp矩阵对象中似乎不能正常工作(而加载std :: vector对象并转换在OpenMP循环完成后到矩阵似乎是解决问题的一个不错的方法)。

Any help would be greatly appreciated! 任何帮助将不胜感激!

To expand on Dirk's answer; 扩展Dirk的答案; R matrices are really just vectors with a dim attribute set 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

Notice how the 'data' component of x and y are just REALSXP s, but you have this extra dim component on the matrix. 注意xy的'data'组件是如何只是REALSXP ,但你在矩阵上有这个额外的dim组件。 Using this, we can easily convert a NumericVector to a matrix in Rcpp . 利用这一点,我们可以将很容易地转换NumericVector在矩阵Rcpp

(Note: in the example below, I use SEXP in the attributes just so the conversions between types are explicit): (注意:在下面的示例中,我在属性中使用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)
*/

gives me 给我

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

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

So, you can use the Dimension class and assign it to the dim attribute of a vector to make a matrix 'by hand' in Rcpp. 因此,您可以使用Dimension类并将其分配给向量的dim属性,以在Rcpp中“手动”生成矩阵。

You chose a good approach. 你选择了一个好的方法。 In the OpenMP context, you have to stay away from the single-threaded R. So std::vector is good. 在OpenMP上下文中,你必须远离单线程R.所以std::vector很好。

And yes, we have constructors from std::vector to Rcpp::NumericVector and Rcpp::NumericMatrix (which is after all just a vector with a dimensions attribute) as well as the Rcoo:Integer* variants, as well as the usual as<> and wrap converters. 是的,我们有从std::vectorRcpp::NumericVectorRcpp::NumericMatrix (毕竟只是一个带有维度属性的向量)的Rcoo:Integer*以及Rcoo:Integer*变体,以及通常as<>wrap转换器。

There should be plenty of examples in the Rcpp unit tests, the Rcpp examples, and of course on the Rcpp Gallery site. Rcpp单元测试,Rcpp示例以及Rcpp Gallery站点上应该有大量示例。

Edit: Here is an overly simple example: 编辑:这是一个非常简单的例子:

 R> cppFunction('NumericVector phil(int n) { std::vector<double> x(n);
 +              return wrap(x); }') 
 R> phil(4)  
 [1] 0 0 0 0    
 R>    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM