looking at the rcpp
documentation and Rcpp::DataFrame
in the gallery I realized that I didn't know how to modify a DataFrame by reference. Googling a bit I found this post on SO and this post on the archive.
There is nothing obvious so I suspect I miss something big like "It is already the case because" or "it does not make sense because".
I tried the following which compiled but the data.frame
object passed to updateDFByRef
in R stayed untouched
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void updateDFByRef(DataFrame& df) {
int N = df.nrows();
NumericVector newCol(N,1.);
df["newCol"] = newCol;
return;
}
The way DataFrame::operator[]
is implemented indeed leeds to a copy when you do that:
df["newCol"] = newCol;
To do what you want, you need to consider what a data frame is, a list of vectors, with certain attributes. Then you can grab data from the original, by copying the vectors (the pointers, not their content).
Something like this does it. It is a little more work, but not that hard.
// [[Rcpp::export]]
List updateDFByRef(DataFrame& df, std::string name) {
int nr = df.nrows(), nc= df.size() ;
NumericVector newCol(nr,1.);
List out(nc+1) ;
CharacterVector onames = df.attr("names") ;
CharacterVector names( nc + 1 ) ;
for( int i=0; i<nc; i++) {
out[i] = df[i] ;
names[i] = onames[i] ;
}
out[nc] = newCol ;
names[nc] = name ;
out.attr("class") = df.attr("class") ;
out.attr("row.names") = df.attr("row.names") ;
out.attr("names") = names ;
return out ;
}
There are issues associated with this approach. Your original data frame and the one you created share the same vectors and so bad things can happen. So only use this if you know what you are doing.
The short answers is "because it makes no sense".
A data.frame
is essentially a list of vectors. A few seconds of reflection makes it clear that adding a new column to that list entails a copy. So you alter your variable df
in the example, do not return it and hence loose the modification.
Merely wishing for something to work a certain way is not always enough.
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