I want to get column names of a matrix to set another one, but if matrix does not have column names (or is set to NULL), the following code crashes my R session.
CharacterVector cn = colnames(x);
The following code is the way how I get column names of a matrix even if it does not have.
#include <Rcpp.h>
using namespace Rcpp;
// Get column names or empty
// [[Rcpp::export]]
CharacterVector get_colnames(const NumericMatrix &x) {
CharacterVector cn;
SEXP cnm = colnames(x);
if (!Rf_isNull(cnm)) cn = cnm;
return(cn);
}
Is there a more elegant way?
I had started this and then got distracted. @coatless covered it, this is simply shorter.
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;
// [[Rcpp::export]]
CharacterVector getColnames(const NumericMatrix &x) {
size_t nc = x.cols();
SEXP s = x.attr("dimnames"); // could be nil or list
if (Rf_isNull(s)) { // no dimnames, need to construct names
CharacterVector res(nc);
for (size_t i=0; i<nc; i++) {
res[i] = std::string("V") + std::to_string(i);
}
return(res);
} else { // have names, return colnames part
List dn(s);
return(dn[1]);
}
}
/*** R
m <- matrix(1:9,3,3)
getColnames(m)
colnames(m) <- c("tic", "tac", "toe")
getColnames(m)
*/
R> Rcpp::sourceCpp("~/git/stackoverflow/55850510/answer.cpp")
R> m <- matrix(1:9,3,3)
R> getColnames(m)
[1] "V0" "V1" "V2"
R> colnames(m) <- c("tic", "tac", "toe")
R> getColnames(m)
[1] "tic" "tac" "toe"
R>