Reputation: 28274
I have started with Rcpp and I am working through Hadley's book / page here. I guess these basics are more than enough for me, still though I missed, some aspect or feel that this might be less basic:
How can I assign attributes to an arbitrary R Object using C++?
E.g.:
// [[Rcpp::export]]
NumericVector attribs(CharacterVector x,NumericVector y) {
NumericVector out = y;
out.attr("my-attr") = x;
return out;
}
I understand I have to specify the type in C++, but still I wonder whether there's a way to assign an attribute to ANY R object that I pass...
I have seen that settatr
in the data.table
works with C++, but seems to work only with elements of class data.table. Is there any way but writing an extra function for every R mode / class?
EDIT: The ultimate purpose is to speed up assigning attributes to each element of a list. We had discussion here previously – but it did not involve Rcpp so far (except for using it via other packages.)
Upvotes: 3
Views: 459
Reputation: 28274
Pardon my enthusiam: It's simply amazing how Rcpp helps an absolute novice to speed up code like that!
That's why I gave it a try though Hadley's answer perfectly covers the question. I tried to turn the input given here into a solution for the more specific case of adding attributes to a list of objects as fast as possible.
Even though my code is probably far from perfect I was already able to outperform all
functions suggested in the discussion, including data.table's setattr
. I guess this is probably due to the fact that I let C++ not only to do the assignment but the looping as well.
Here's the example and benchmark:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
RObject fx(List x, CharacterVector y){
int n = x.size();
NumericVector new_el;
for(int i=0; i<n; i++) {
new_el = x[i];
new_el.attr("testkey") = y;
x[i] = new_el;
}
return(x);
}
Upvotes: 0
Reputation: 103948
Maybe you want something like this? RObject
is the generic class for all R objects. Note the use of clone
so that you don't accidentally modify the object passed in.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
CharacterVector set_attr(CharacterVector x, RObject y) {
CharacterVector new_x = clone(x);
new_x.attr("my-attr") = y;
return new_x;
}
/*** R
x <- c("a", "b", "c")
set_attr(x, 1)
set_attr(x, "a")
attributes(x)
*/
Upvotes: 5