如何访问Rcpp::List中向量的元素

10

我感到困惑。

以下代码编译并且正常工作:

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List test(){
    List l;
    IntegerVector v(5, NA_INTEGER);
    l.push_back(v);
    return l;
}

在 R 中:

R) test()
[[1]]
[1] NA NA NA NA NA

但是当我尝试设置列表中的IntegerVector时:

// [[Rcpp::export]]
List test(){
    List l;
    IntegerVector v(5, NA_INTEGER);
    l.push_back(v);
    l[0][1] = 1;
    return l;
}

它不能编译:

test.cpp:121:8: error: invalid use of incomplete type 'struct SEXPREC'
C:/PROGRA~1/R/R-30~1.0/include/Rinternals.h:393:16: error: forward declaration of 'struct SEXPREC'
1个回答

16
这是因为这一行代码:
l[0][1] = 1;

编译器不知道变量l是由整数向量组成的列表。实质上,l[0]给出了一个SEXP对象(所有R对象的通用类型),而SEXP是指向SEXPREC的不透明指针,我们无法访问其定义(因此为不透明)。因此,当使用[1]时,你尝试获取第二个SEXPREC,不透明性使其不可能,并且这也不是你想要的结果。
你必须明确提取一个IntegerVector,可以像这样操作:
as<IntegerVector>(l[0])[1] = 1;

或者
v[1] = 1 ;

或者
IntegerVector x = l[0] ; x[1] = 1 ;

所有这些选项都使用相同的底层数据结构。
或者,如果你真的想要语法l[0][1],你可以定义自己的数据结构,表示“整数向量列表”。以下是一个简要草图:
template <class T>
class ListOf {
public:

    ListOf( List data_) : data(data_){}

    T operator[](int i){
        return as<T>( data[i] ) ;
    }
    operator List(){ return data ; }

private:
    List data ;
} ;

您可以像这样使用它,例如:
// [[Rcpp::export]]
List test2(){
    ListOf<IntegerVector> l = List::create( IntegerVector(5, NA_INTEGER) ) ; 
    l[0][1] = 1 ;
    return l;
}

请注意,对于 Rcpp 向量(包括列表),使用 .push_back 需要完全复制列表数据,这可能会使你的程序变慢。只有在没有其他选择时才使用调整大小功能。


Romain,另外一个问题,我能否创建一个包含n(比如3)个std::vector<int>或者Rcpp::IntegerVectorRcpp::List,并且使用一行代码(可能是构造函数)来完成,例如IntegerVector v(3,NA_INTEGER); Rcpp::List test(3,v) - statquant
这段代码本意是要运行的:List l( 3, IntegerVector(3,NA_INTEGER) ),但我们的一个文件中有一个错别字(fill__dispatch被拼写成了fill_dispatch(只有一个下划线)),导致它无法正常工作。我已经在本地修复了它,并很快会提交修复。 - Romain Francois

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接