I am puzzled.
The following compile and work fine:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List test(){
List l;
IntegerVector v(5, NA_INTEGER);
l.push_back(v);
return l;
}
In R:
R) test()
[[1]]
[1] NA NA NA NA NA
But when I try to set the IntegerVector
in the list:
// [[Rcpp::export]]
List test(){
List l;
IntegerVector v(5, NA_INTEGER);
l.push_back(v);
l[0][1] = 1;
return l;
}
It does not compile:
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'
Accessing List Elements. Elements of the list can be accessed by the index of the element in the list. In case of named lists it can also be accessed using the names.
To check if a vector exists in a list, we can use %in%, and read the vector as list using list function. For example, if we have a list called LIST and a vector called V then we can check whether V exists in LIST using the command LIST %in% list(V).
Description The 'Rcpp' package provides R functions as well as C++ classes which offer a seamless integration of R and C++. Many R data types and objects can be mapped back and forth to C++ equivalents which facilitates both writing of new code as well as easier integration of third-party libraries.
Rcpp Sugar is bases on expression templates and provides some. syntactic sugar facilities direclty in Rcpp. suppressMessages(library(Rcpp)) ## Warning: package Rcpp was built under R version 3.1.3. suppressMessages(library(RcppArmadillo))
It is because of this line:
l[0][1] = 1;
The compiler has no idea that l
is a list of integer vectors. In essence l[0]
gives you a SEXP
(the generic type for all R objects), and SEXP
is an opaque pointer to SEXPREC
of which we don't have access to te definition (hence opaque). So when you do the [1]
, you attempt to get the second SEXPREC
and so the opacity makes it impossible, and it is not what you wanted anyway.
You have to be specific that you are extracting an IntegerVector
, so you can do something like this:
as<IntegerVector>(l[0])[1] = 1;
or
v[1] = 1 ;
or
IntegerVector x = l[0] ; x[1] = 1 ;
All of these options work on the same underlying data structure.
Alternatively, if you really wanted the syntax l[0][1]
you could define your own data structure expressing "list of integer vectors". Here is a sketch:
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 ;
} ;
Which you can use, e.g. like this:
// [[Rcpp::export]]
List test2(){
ListOf<IntegerVector> l = List::create( IntegerVector(5, NA_INTEGER) ) ;
l[0][1] = 1 ;
return l;
}
Also note that using .push_back
on Rcpp
vectors (including lists) requires a complete copy of the list data, which can cause slow you down. Only use resizing functions when you don't have a choice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With