有没有一种简单的方法可以在 Rcpp 中生成多维数组并将该数组导出到 R

Mad*_*chs 0 arrays r rcpp

我正在寻找一种简单的方法来使用 Rcpp 构建 3D 数组,并使该数组可以在 R 中访问。总的来说,我对 Rcpp 和 C++ 编码仍然很陌生,因此我们将不胜感激。

\n

这是我的源代码:

\n
#include <Rcpp.h>\nusing namespace Rcpp;\n\n\nint d[5][5][5] = {0};\n\n// [[Rcpp::export]]\n\nint fit(){ \n  for (int X = 0; X < 5; X++){\n    for (int Y = 0; Y < 5; Y++){\n      for (int Z = 0; Z < 5; Z++){\n        d[X][Y][Z] = X + Y + Z;\n      }\n    }\n  }\nreturn d;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我的想法是我可以将 fit() 分配给 R 中的一个元素(比如 D),并且能够从该数组中的位置进行调用。

\n

我意识到我可以让“拟合”成为 x、y 和 z 的函数;但就我的目的而言,在 R 中使用数组会更快。

\n

再次强调,任何帮助将不胜感激。

\n

编辑

\n

感谢您的帮助,德克,\n我仍在努力解决的一件事是运行循环。当我运行这个循环时:

\n
#include <Rcpp.h>\n\nusing namespace Rcpp;\n\n// [[Rcpp::export]]\nIntegerVector rcpp_matrix(){\n\n  IntegerVector v = IntegerVector(Dimension(2,2));\n  \n  for (int i = 0; i < 2; i++){\n    for (int j = 0; j < 2; j++){\n        v(i,j) = (i + 1) * (j + 1);\n    }\n  }\n  \n  // Return the vector to R\n  return v;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

它按预期工作。然而,当我尝试扩展到三个维度时,如下所示:

\n
#include <Rcpp.h>\n\nusing namespace Rcpp;\n\n// [[Rcpp::export]]\nIntegerVector rcpp_matrix(){\n\n  IntegerVector v = IntegerVector(Dimension(2,2,2));\n  \n  for (int i = 0; i < 2; i++){\n    for (int j = 0; j < 2; j++){\n      for (int k = 0; k < 2; k++){\n        v(i,j,k) = (i + 1) * (j + 1) * (k + 1);\n      }\n    }\n  }\n  \n  // Return the vector to R\n  return v;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我收到错误:

\n
file10c2d06d0b.cpp: In function \xe2\x80\x98Rcpp::IntegerVector rcpp_matrix()\xe2\x80\x99:\nfile10c2d06d0b.cpp:14:16: error: no match for call to \xe2\x80\x98(Rcpp::IntegerVector {aka Rcpp::Vector<13>}) (int&, int&, int&)\xe2\x80\x99\n   14 |         v(i,j,k) = (i + 1) * (j + 1) * (k + 1);\n      |                ^\n
Run Code Online (Sandbox Code Playgroud)\n

我还缺少其他方面吗?\n再次感谢您。

\n

Dir*_*tel 7

向量是 R 中的关键,数组只是具有二维属性的向量:

> v <- 1:12
> dim(v) <- c(3,4)
> v
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> 
Run Code Online (Sandbox Code Playgroud)

所以我们也可以做 3-d:

> dim(v) <- c(2,3,2)
> v
, , 1

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

, , 2

     [,1] [,2] [,3]
[1,]    7    9   11
[2,]    8   10   12

> 
Run Code Online (Sandbox Code Playgroud)

等等。这与 Rcpp 中的单元测试片段中看到的完全相同:

// [[Rcpp::export]]
IntegerVector integer_dimension_ctor_3(){
    return IntegerVector( Dimension( 2, 3, 4) ) ;
}
Run Code Online (Sandbox Code Playgroud)

我们可以快速测试:

> Rcpp::cppFunction("IntegerVector ivec3() { return IntegerVector(Dimension(2, 3, 4));}")
> ivec3()
, , 1

     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

, , 2

     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

, , 3

     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

, , 4

     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

> 
Run Code Online (Sandbox Code Playgroud)

话虽如此,我建议您研究一下 Armadillo 'Cubes' 以及您可以从 RcppArmadillo 做什么 - 可能功能更齐全。

编辑: 这是你的方法的更简单的犰狳变体,使用cube<int>又名icube

代码

#include <RcppArmadillo/Lightest> // new 'lighter' header

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::icube make3dvec(){
    arma::icube v(2,2,2);
    for (int x = 0; x < 2; x++){
        for (int y = 0; y < 2; y++){
            for (int z = 0; z < 2; z++){
                v(x,y,z) = (x + 1) * (y + 1) * (z + 1);
            }
        }
    }
    return v;
}

/*** R
make3dvec()
*/
Run Code Online (Sandbox Code Playgroud)

输出

> Rcpp::sourceCpp("~/git/stackoverflow/75036466/answer.cpp")

> make3dvec()
, , 1

     [,1] [,2]
[1,]    1    2
[2,]    2    4

, , 2

     [,1] [,2]
[1,]    2    4
[2,]    4    8

> 
Run Code Online (Sandbox Code Playgroud)