Reputation: 5692
In a function, I want to calculate numeric values, give names to them and return a sorted NumericVector
in Rcpp. I can sort the vectors (using this), but the order of the names of the values remains the same.
library(Rcpp)
x <- c(a = 1, b = 5, c = 3)
cppFunction('
NumericVector foo(NumericVector x) {
std::sort(x.begin(), x.end());
return(x);
}')
foo(x)
## a b c
## 1 3 5
I want the function to return this:
## a c b
## 1 3 5
Is it possible? How can I achieve this?
Upvotes: 9
Views: 331
Reputation: 5692
Using the tip Dirk gave in his comment, I figured out that names of x
is just another vector. So, I searched for sorting a vector using another vector. Using this SO answer I come up with following two solutions:
library(Rcpp)
x = c(a = 1, b = 5, c = 3, d = -3.2)
cppFunction('
NumericVector foo1(NumericVector x) {
IntegerVector idx = seq_along(x) - 1;
std::sort(idx.begin(), idx.end(), [&](int i, int j){return x[i] < x[j];});
return x[idx];
}')
foo1(x)
## d a c b
## -3.2 1.0 3.0 5.0
cppFunction('
NumericVector foo2(NumericVector x) {
IntegerVector idx = seq_along(x) - 1;
//// Ordered indices based on x:
std::sort(idx.begin(), idx.end(), [&](int i, int j){return x[i] < x[j];});
//// Get the names of x:
CharacterVector names_of_x = x.names();
//// y vector is sorted x
NumericVector y = x[idx];
//// Assign sorted names to y vector as names
y.attr("names") = names_of_x[idx];
return y;
}')
foo2(x)
## d a c b
## -3.2 1.0 3.0 5.0
Upvotes: 5