Я хочу преобразовать список, например, так:
[[1]]
[1] 3 4 99 1 222
[[2]]
[1] 1 2 3 4 5
к матрице (2,5) в Rcpp.
Какой самый быстрый способ сделать это?
Функция wrap () в этом случае не работает.
Сначала я попытался преобразовать список в вектор, а затем в матрицу. Использование wrap () в функции:
#include <Rcpp.h>
using namespace Rcpp ;// [[Rcpp::export]]
NumericVector mat(List a){
NumericVector wynik;
wynik = Rcpp::wrap(a);
return wynik;
}
/***R
mat(list(c(3,4,99,1,222), c(1,2,3,4,5)))
*/
Я получаю ошибку:
> mat(list(c(3,4,99,1,222), c(1,2,3,4,5)))
Error in eval(substitute(expr), envir, enclos) :
not compatible with requested type
Вместо cbind
а также t
только для одной итерации, возможно, было бы лучше инициализировать матрицу, а затем заполнить строку необходимой размерной проверкой.
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix make_mat(Rcpp::List input_list){
unsigned int n = input_list.length();
if(n == 0) {
Rcpp::stop("Must supply a list with more than 1 element.");
}
Rcpp::NumericVector testvals = input_list[0];
unsigned int elems = testvals.length();
Rcpp::NumericMatrix result_mat = Rcpp::no_init(n, elems);
// fill by row
for(unsigned int i = 0; i < n; i++) {
Rcpp::NumericVector row_val = input_list[i];
if(elems != row_val.length()) {
Rcpp::stop("Length of row does not match matrix requirements");
}
result_mat(i, Rcpp::_) = row_val;
}
return result_mat;
}
make_mat(list(c(3,4,99,1,222), c(1,2,3,4,5)))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 3 4 99 1 222
# [2,] 1 2 3 4 5
Я использовал функции сахара Rcpp::cbind
а также Rcpp::transpose
,
Код:
#include <Rcpp.h>
using namespace Rcpp ;// [[Rcpp::export]]
NumericMatrix mat(List a){
NumericVector a1;
NumericVector a0;
NumericMatrix b;
a1 = a[1];
a0 = a[0];
b = Rcpp::cbind(a0, a1);
b = Rcpp::transpose(b);
return b;
}
И мы получаем:
> mat(list(c(3,4,99,1,222), c(1,2,3,4,5)))
[,1] [,2] [,3] [,4] [,5]
[1,] 3 4 99 1 222
[2,] 1 2 3 4 5