0

I would like to be able, via a function, to modify a sub part of a Rcpp::List. Since Rcpp::List is a pointer to some R data, I thought it would be possible to do something like this:

void modifyList(Rcpp::List l) {
  l["x"] = "x";
}

// [[Rcpp::export]]
Rcpp::List rcppTest() {
  Rcpp::List res;
  res["a"] = Rcpp::List::create();
  modifyList(res["a"]);
  return res;
}

I expected to get as return value of rcppTest a list with an element "x" of value "x". The returned list is empty however.

If instead I use the signature modifyList(Rcpp::List& l), I get a compilation error

rcppTest.cpp:17:6: note: candidate function not viable: no known conversion from 'Rcpp::Vector<19, PreserveStorage>::NameProxy' (aka 'generic_name_proxy<19, PreserveStorage>') to 'Rcpp::List &' (aka 'Vector<19> &') for 1st argument

How can I modify a a sub part of an Rcpp::List via a function ?

coatless
  • 20,011
  • 13
  • 69
  • 84
vkubicki
  • 1,104
  • 1
  • 11
  • 26
  • 3
    I think that has been discussed before (possibly in the contect of `DataFrame` object, which are really `List` underneath) -- it just won't work reason of the R types under it. So you mayl have to write a helper functions that copies the existing list and then alters. Or keep an STL list as long as possible and convert just before return... – Dirk Eddelbuettel Aug 24 '18 at 14:27
  • 1
    See [here](https://stackoverflow.com/questions/51879038/how-can-i-add-a-new-column-to-dataframe-in-rcpp) for a similar problem. Your example will work if `modifyList` returns the list and the result is properly assigned. – Ralf Stubner Aug 24 '18 at 14:37

2 Answers2

3

In short, modifying a list by reference isn't possible. In this case, you must return the Rcpp::List as @RalfStubner points out from the comments.

e.g.

#include<Rcpp.h>

// Specified return type of List
Rcpp::List modifyList(Rcpp::List l) {
  l["x"] = "x";
  return l;
}

// [[Rcpp::export]]
Rcpp::List rcppTest() {
  Rcpp::List res;
  res["a"] = Rcpp::List::create();

  // Store result back into "a"
  res["a"] = modifyList(res["a"]);

  return res;
}

Test:

rcppTest()
# $a
# $a$x
# [1] "x"
coatless
  • 20,011
  • 13
  • 69
  • 84
0

This works:

// [[Rcpp::export]]
void modifyList(List& l, std::string i) {
  l[i]= "x";
}

// [[Rcpp::export]]
Rcpp::List rcppTest() {
  Rcpp::List res;
  res["a"] = Rcpp::List::create();
  modifyList(res,"a");
  return res;
}

and gives:

> rcppTest()
$`a`
[1] "x"

The problem is you are trying to:

error: invalid initialization of non-const reference of type 'Rcpp::List& {aka Rcpp::Vector<19>&}'
theogrost
  • 21
  • 2