【问题标题】:Rcpp: Dealing with Lists that include ListsRcpp:处理包含列表的列表
【发布时间】:2014-01-21 05:10:38
【问题描述】:

让我们首先生成一些列表,里面有列表:

lappend <- function(lst, ...){
  lst <- c(lst, list(...))
  return(lst)
}

scalarList <- list()
vectorList <- list()
MatrixList <- list()

for (i in 1:3){
  scalarList <- lappend(scalarList,i)
  vectorList <- lappend(vectorList,0:i)
  MatrixList <- lappend(MatrixList, diag(i + 1))
}

myRList <- list(scalarList = scalarList, vectorList = vectorList, 
  MatrixList = MatrixList)

现在我们的 myRList 已经准备好了,我想用 C++ 编写一个函数,如下所示:

1) 输入:1) myRList,2) 从 1 到 3 的 id

2) 输出:函数应该分别打印输入id对应的标量、向量和矩阵。

3) 编写这个函数可能有很多方法。我特别想读入列表并将其分配给相应的 arma 对象,然后打印它。原因是我写了这个简化的例子来向你们学习如何在 Rcpp 中提取另一个列表中的列表元素并将其分配给 arma 对象。

这是我的 C++ 代码:

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

// [[Rcpp::export]]
double myListExtractor( Rcpp::List aList_In_R, int id){
int myScalar = Rcpp::as<double>(aList_In_R["scalarList"][id]); //? what to do ?
arma::vec myVector = Rcpp::as<arma::vec>(aList_In_R["vectorList"[id]]); //???
arma::mat myMatrix = Rcpp::as<arma::mat>(aList_In_R["MatrixList"[id]]); //???

// If I manage to do the three assignments above, then printing is easy:

Rcpp::Rcout << "myScalar = " << myScalar << std::endl;
Rcpp::Rcout << "myVector = " << myVector << std::endl; 
Rcpp::Rcout << "myMatrix = " << myMatrix << std::endl;

return 1; // we don't care about the return for now
}

再一次,我 100% 同意没有必要将它们分配给 arma 对象然后打印。在我自己的代码中,我对 arma 对象做了很多代数,这就是我强调这项作业以学习如何修复我的代码的原因/

非常感谢您的帮助。另外,我花了 3 个小时浏览了网络,但没有找到任何答案。

【问题讨论】:

  • 一种解决方案是在每个子列表上调用函数,或者不调用 myRList 上的函数,我们可以为函数提供三个参数 myRList$scalarList、myRList$vectorList 和 myRList$ MatrixList 和每个单独工作
  • 搜索 [rcpp] List 有 183 个结果。你先搜索了吗?
  • @DirkEddelbuettel,早上好。是的,我做到了。正如您在书中所解释的那样,从列表中检索元素有很多有用的答案。我没有找到关于处理包含子列表的列表的任何问题/答案。
  • 我很确定我们也在某个地方回答了这个问题。 在概念上确实是一样的:你从一个列表中获取一个SEXP。这恰好是一个列表,您可以从中获取 SEXP ...
  • 你说得对——这是this question的副本。

标签: c++ r rcpp armadillo


【解决方案1】:

因为List 对象不知道它们包含的对象类型,所以您必须在每个子集级别上使用as。例如:

int myScalar = Rcpp::as<double>( Rcpp::as<Rcpp::List>(aList_In_R["scalarList"])[id] );

这样,我们可以向编译器发出信号,我们从aList_In_R 提取的槽是List,我们为Lists 提供的所有方法都应该在这里应用。这很丑陋,但它是使用静态类型语言来操作动态类型语言中使用的对象的不幸结果。

有一些工作可以将模板列表容器放入Rcpp,这可能有助于解决这种情况;例如而不是List,您可能有一个ListOf&lt; List &gt;,子集运算符将“知道”它应该在子集化后返回List,这可能会更好一些。也许它可以深入到ListOf&lt; ListOf&lt; double &gt; &gt; 等......

【讨论】:

  • 嗨@KevinUshey,完美的答案。我的问题现在完全解决了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2018-01-09
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
相关资源
最近更新 更多