"List"对象在rcpp中的操作

Operation of "List" object in rcpp

Rcpp中对List对象的一些操作我很确定,比如获取元素个数,引用第i个元素等...代码如下,其中X 这里是 List 行数相同的矩阵。

#include <RcppArmadillo.h> 
// [[Rcpp::depends(RcppArmadillo)]]

#include <Rcpp.h>
using namespace arma;
using namespace Rcpp;
using namespace std;
using namespace sugar;

// [[Rcpp::export]]
List Test_C(mat Y, List X){       
  int K = X.n_elem; //I was trying to get the # of elems of X
  mat X1 = X[1];    //I was trying to get the first matrix in X
  mat YX1 = [Y, X1]; //I was trying to combine Y and X1 to one matrix.
  List out;
  out["K"] = K;
  out["X1"] = X1;
  out["YX1"] = YX1;
  return(out);
}

我获取了这段代码并在 R 中调用它:(YX 在 R 中定义明确)

Test_C(Y, X);

但显然出了点问题。

我刚刚发现:

mat X1 = X[0];  
mat YX1 = join_rows(Y, X1);

是正确的,但我仍然不知道如何获取 "List" 对象的元素数。我认为这应该是非常基本的东西...

我假设您的最终目标是推广 YX 中所有矩阵的连接,所以这就是我解决以下问题的方法:

#include <RcppArmadillo.h> 
// [[Rcpp::depends(RcppArmadillo)]]

struct fill_from_list {
  fill_from_list(const arma::mat& init)
    : x(init) {}
  void operator()(const arma::mat& m) {
    x = arma::join_rows(x, m);
  }
  arma::mat x;
};

arma::mat accum_join(const arma::mat& init, Rcpp::List X) {
  return std::for_each(X.begin(), X.end(), fill_from_list(init)).x;
}

// [[Rcpp::export]]
Rcpp::List Test_C2(const arma::mat& Y, Rcpp::List X) {
  return Rcpp::List::create(
    Rcpp::Named("K") = X.size(),
    Rcpp::Named("X1") = X[0],
    Rcpp::Named("YXK") = accum_join(Y, X));
}

详细说明一下,函数对象 fill_from_list 是用初始 arma::mat 构造的,每次通过 operator() 向其传递一个额外的 arma::mat,使用 arma::join_rows.

使用输入的列更新数据成员 x

这个仿函数在辅助函数 accum_join 中使用,它采用适当的输入对象和 return 通过使用 std::for_each 算法(注意尾随 .x - for_each 本身没有 return 值 )。

最后一个函数 return 是您问题中显示的样式列表,除了第三个元素现在是 Y 和所有 X 元素的串联, 而不是 YX.

的第一个元素

与您的原始函数相比 -

// [[Rcpp::export]]
Rcpp::List Test_C(arma::mat Y, Rcpp::List X){       
  int K = X.size(); 
  arma::mat X1 = X[0];    
  arma::mat YX1 = arma::join_rows(Y, X1); 
  Rcpp::List out;
  out["K"] = K;
  out["X1"] = X1;
  out["YXK"] = YX1;
  return out;
}

我们有:

mlist <- lapply(1:4, function(x) matrix(x, nrow = 3, ncol = x))

> all.equal(Test_C(mlist[[1]], mlist[2]), Test_C2(mlist[[1]], mlist[2]))
[1] TRUE

## including matrices 3 and 4:
> Test_C2(mlist[[1]], mlist[2:4])
$K
[1] 3

$X1
     [,1] [,2]
[1,]    2    2
[2,]    2    2
[3,]    2    2

$YXK
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    2    2    3    3    3    4    4    4     4
[2,]    1    2    2    3    3    3    4    4    4     4
[3,]    1    2    2    3    3    3    4    4    4     4

为了澄清你的另一个问题,

int K = X.n_elem; //I was trying to get the # of elems of X

你想要 X.size()Rcpp:: 方法),而不是 X.n_elemarma:: 方法)。