2012-09-24 11 views
6

Próbuję odwzorować tablicę 1D na tablicę 3D, korzystając z podanej listy wymiarów.Tworzenie tablicy 3D w Rcpp

Oto moje składniki:

SEXP data; // my 1D array 
// I can initialise new 3D vector in the following way: 
NumericVector vector(Dimension(2, 2, 2); 
// or the following: 
NumericVector vector(data.begin(), data.end()); 

Co mi się nie zorientować się, to w jaki sposób można stworzyć NumericVector które mają zarówno swoje dane i pożądanych wymiarów.

+1

Przykład z * RcppArmadillo kostki *: http://markovjumps.blogspot.be/2011/12/r-array-to-rcpparmadillo-cube.html –

Odpowiedz

5

Jest to wykonalne, ale trochę bolesne. Domyślam się, że przyzwoity (i przetestowany) wkład dla nowego konstruktora lub funkcji pomocnika byłby doceniony.

W międzyczasie możesz zrobić to, co robi poniższy przykład. Ale bądź ostrożny z rzędu-major i col-dur itd. Inną opcją jest RcppArmadillo, która ma odpowiednią macierz generalizującą typu "Cube" do 3-d.

R> library(inline) 
R> fx <- cxxfunction(signature(vs="numeric", ds="integer"), plugin="Rcpp", body=' 
+ Rcpp::NumericVector v(vs);   // get the data 
+ Rcpp::Dimension d(ds);    // get the dim object 
+ Rcpp::NumericVector r(d);    // create vec. with correct dims 
+ std::copy(v.begin(), v.end(), r.begin()); // and copy 
+ return Rcpp::List::create(v, d, r); 
+ ') 
R> fx(1:8, c(2,2,2)) 
[[1]] 
[1] 1 2 3 4 5 6 7 8 

[[2]] 
[1] 2 2 2 

[[3]] 
, , 1 

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

, , 2 

    [,1] [,2] 
[1,] 5 7 
[2,] 6 8 


R> 
+0

Zgadzam się z nowym konstruktora, będzie bardzo przydatne. Mogę się temu przyjrzeć, kiedy zrozumiem, jak działają rzeczy w Rcpp. – Datageek

+1

FWIW, dodanie kolejnego konstruktora do już nadętego szablonu 'Vector' wydaje się złym pomysłem. Możesz osiągnąć to samo z darmową funkcją lub dedykowaną klasą Array, taką jak ta w Rcpp11. –

+2

Dziękujemy za zaktualizowanie dwuletniej odpowiedzi. FWIW Używam RcppArmadillo przy kilku okazjach, ponieważ Armadillo ma 'Cube' jako obiekt pierwszej klasy. Pracuje dla mnie. –

10

Istnieje krótsze rozwiązanie. Możesz zmienić swoje dane za pomocą .attr. Dane mogą być tworzone lub podawane jako dane wejściowe - nie ma to znaczenia. Patrz poniżej:

library("Rcpp") 

cppFunction(code=' 
NumericVector arrayC(NumericVector input, IntegerVector dim) { 
    input.attr("dim") = dim; 
    return input; 
} 
') 
x = 1:8 
arrayC(x, c(2,2,2)) 
## , , 1 
## 
##  [,1] [,2] 
## [1,] 1 3 
## [2,] 2 4 
## 
## , , 2 
## 
##  [,1] [,2] 
## [1,] 5 7 
## [2,] 6 8