In Rcpp - how to return a vector with names

r, rcpp

Solution

To set the landscape:

- Regular R vectors have an (optional) `names` attribute,

- `data.frame`s have a `row.names` attribute for rows, and `names` attribute for columns, and

- `matrix`s have an (optional) `dimnames` attribute; this attribute is a `list` containing 2 character vectors (rows then columns).

So what you want is the column names of `x` attached to the 'names' attribute of `out`, so something like:

out.attr("names") = VECTOR_ELT(x.attr("dimnames"), 1);

would work.

(I cannot recall if `Rcpp` has a nice API for getting / setting dimension names in arrays...)

Problem

Suppose I have the following matrix: ``` testM <- as.matrix(read.table(textConnection(" 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 5 4 1 3 2 2 1 "))) ``` This matrix has column names `V1` to `V6` Suppose that there is another matrix where I remove the column name: ``` > testM2<-testM > colnames(testM2)<-NULL ``` Then if I try `colMeans` on `testM` and `testM2` R returns a `numeric` class in both cases, except in the first case the answer has `colnames`. ``` > colMeans(testM) V1 V2 V3 V4 V5 V6 2.166667 2.333333 2.833333 2.500000 2.666667 2.666667 > colMeans(testM2) [1] 2.166667 2.333333 2.833333 2.500000 2.666667 2.666667 ``` Now suppose I have the same function written in RCpp as follows: ``` double do_mean(NumericVector x) { return mean(na_omit(x)); } //[[Rcpp::export]] NumericVector colMeansCppMt(NumericMatrix& x) { int nCols=x.ncol(); NumericVector out=no_init(nCols); for (int i=0;i<nCols;i++) { NumericMatrix::Column tmp=x(_,i); out[i]=do_mean(tmp); } return out; } ``` The output for `colMeansCppMt` for both `testM` and `testM2` return numeric vectors, but the one for `testM` does not contain the `colnames` as it hasn't been set. Now, suppose I change the `colMeansCppMt` function to include attributes like this: ``` //[[Rcpp::export]] NumericVector colMeansCppMt(NumericMatrix& x) { int nCols=x.ncol(); NumericVector out=no_init(nCols); for (int i=0;i<nCols;i++) { NumericMatrix::Column tmp=x(_,i); out[i]=do_mean(tmp); } out.attr("names")=x.attr("names"); return out; } ``` The output for `testM` is still a vector that doesn't contain the column names. I also tried `out.attr("names")=x.attr("colnames")` and `out.attr("colnames")=x.attr("colnames")`. a). How can I check in RCpp where the `colnames` of a matrix (e.g. `x` in the example function above) has been set or not? b). How can I return a numeric vector in R with names in Rcpp?

Original source