Rcpp: dynamically update a list

夙愿已清 提交于 2019-12-06 13:30:20

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

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!