Question

I am seeking solutions to dynamically updating a list.

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List Test(){
List L;
List L1=List::create(12,45,22,44);
L=Language("c",L,L1).eval();//update, add L1's elements on L's back.
return L;
}

The above doesn't work since "List L;" makes L an empty list.

However, if I write an additional function:

List connectlist(List& a, List& b){
return Language("c",a,b).eval();
}

and replace "L=Language("c",L,L1).eval();" with "connectlist(L,L1);", it will work.

Can anyone tell me the reason? Or is there any simpler way to dynamically update a list in Rcpp?

PS: I made some time tests and they showed calling "c" function to combine 2 lists is faster than making a new list by copying elements from the 2 lists.

Thanks!

Was it helpful?

Solution

It appears that Rcpp's List::operator= is broken. With this code:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void Test(){
  List L;
  List L1=List::create(12,45,22,44);
  SEXP x=Language("c",L,L1).eval();//update, add L1's elements on L's back.
  Rprintf( "x = " ) ; Rf_PrintValue(x) ; Rprintf( "\n") ;

  L = x;
  Rprintf( "L = " ) ; Rf_PrintValue(L) ; Rprintf( "\n") ;

}

I get this with the current devel version of Rcpp.

> Test()
x = [[1]]
[1] 12

[[2]]
[1] 45

[[3]]
[1] 22

[[4]]
[1] 44


L = list()

which is wrong. However, I get something correct with Rcpp11:

> Test()
x = [[1]]
[1] 12

[[2]]
[1] 45

[[3]]
[1] 22

[[4]]
[1] 44


L = [[1]]
[1] 12

[[2]]
[1] 45

[[3]]
[1] 22

[[4]]
[1] 44

OTHER TIPS

You are making the same mistake as in your last question.

C++ is C++. And R is R. And they are different.

Just because you know a c() function / operator in R does not mean that this is how to do in C++. You should probably read some C++ or programming texts -- there are equivalent data structures to grow object and to append. Many of us like the STL for this, and Rcpp helps you get your R data to and from it easily.

Edit on 2014-03-12 Thanks to a commit by Kevin, this now also works in the release candidate Rcpp 0.11.1 which should hit CRAN in a few days (and which you can get from GitHub now).

R> library(Rcpp)
R> packageDescription("Rcpp")$Version
[1] "0.11.1"                             # as on GitHub, to be on CRAN soon
R> sourceCpp("/tmp/listconcat.cpp")
R> Test()
x = [[1]]
[1] 12

[[2]]
[1] 45

[[3]]
[1] 22

[[4]]
[1] 44


L = [[1]]
[1] 12

[[2]]
[1] 45

[[3]]
[1] 22

[[4]]
[1] 44


R> 

It is still the wrong programming idiom to concatenate two C++ lists via a call to R, but if someone really insists on doing it, well now they can.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top