I have a function to SORT:
// https://gallery.rcpp.org/articles/sorting/
// https://www.geeksforgeeks.org/sorting-a-vector-in-c/
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector cpp_sort_numeric_works(NumericVector arr, std::string dir = "ASC" )
{
NumericVector _arr = clone(arr);
if(dir != "ASC")
{
std::sort(_arr.begin(), _arr.end(), std::greater<int>());
}
else {
std::sort(_arr.begin(), _arr.end());
}
return _arr;
}
/*
NumericVector _partial_sort(NumericVector arr, int p, std::string dir = "ASC")
{
NumericVector _arr = clone(arr);
if(dir != "ASC")
{
std::nth_element(_arr.begin(), _arr.begin() p-1, _arr.end(), std::greater<int>());
}
else {
std::nth_element(_arr.begin(), _arr.begin() p-1, _arr.end());
}
return _arr;
}
// [[Rcpp::export]]
NumericVector cpp_sort_numeric(NumericVector arr, std::string dir = "ASC", const std::vector<int>& partial={-1} )
{
NumericVector _arr = clone(arr);
if(partial[0] == -1) // only positive values allowed ...
{
if(dir != "ASC")
{
std::sort(_arr.begin(), _arr.end(), std::greater<int>());
}
else {
std::sort(_arr.begin(), _arr.end());
}
}
else {
for (auto& p : partial)
{
_arr = _partial_sort(_arr, p, dir);
}
}
return _arr;
}
*/
If partial = {-1}
, I will treat this like NULL in the base R
setup.
// [[Rcpp::export]]
NumericVector cpp_sort_numeric(NumericVector arr, std::string dir = "ASC", const std::vector<int>& partial={-1} )
The function worked fine before adding the partial
logic. I could be misunderstanding what the partial is doing.
This demo https://gallery.rcpp.org/articles/sorting/ suggests that partial is a scalar, but I believe it is a positive INTEGER array / vector. So I am trying to apply it correctly.
I am getting an Rcpp
warning
Warning: No function found for Rcpp::export attribute at sort.cpp
pointing to the line PRIOR to
NumericVector cpp_sort_numeric(NumericVector arr, std::string dir = "ASC", const std::vector<int>& partial={-1} )
Update
The goal was to implement something that is backward-compatible with the R
sort function. The article [https://gallery.rcpp.org/articles/sorting/] made the inference that it was possible, but did not implement a multivariate partial
object.
@dirk-eddelbuettel solution is syntax-correct, but it is not returning the same values as R-base
# FROM ?sort HELP
require(stats);
x <- swiss$Education[1:25]
x; sort(x); (y = sort(x, partial = c(10, 15)) )
w = c(10,15);
(z = cpp_sort_numeric(x, w))
identical(y,z);
CodePudding user response:
Here is a version that at least compiles and runs. I am not quite sure what you want with partial
-- but what you had is simply outside the (documented, but we already know you do not have time for the documentation we provide) interface contract so of course it didn't build.
Code
// https://gallery.rcpp.org/articles/sorting/
// https://www.geeksforgeeks.org/sorting-a-vector-in-c/
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector cpp_sort_numeric_works(NumericVector arr, std::string dir = "ASC" ) {
NumericVector _arr = clone(arr);
if(dir != "ASC") {
std::sort(_arr.begin(), _arr.end(), std::greater<int>());
} else {
std::sort(_arr.begin(), _arr.end());
}
return _arr;
}
NumericVector _partial_sort(NumericVector arr, int p, std::string dir = "ASC") {
NumericVector _arr = clone(arr);
if(dir != "ASC") {
std::nth_element(_arr.begin(), _arr.begin() p-1, _arr.end(), std::greater<int>());
} else {
std::nth_element(_arr.begin(), _arr.begin() p-1, _arr.end());
}
return _arr;
}
// [[Rcpp::export]]
NumericVector cpp_sort_numeric(NumericVector arr, NumericVector partial, std::string dir = "ASC") {
NumericVector _arr = clone(arr);
if (partial[0] == -1) { // only positive values allowed ...
if(dir != "ASC") {
std::sort(_arr.begin(), _arr.end(), std::greater<int>());
} else {
std::sort(_arr.begin(), _arr.end());
}
} else {
for (auto& p : partial) {
_arr = _partial_sort(_arr, p, dir);
}
}
return _arr;
}
/*** R
v <- c(1,2,3,2,1,0,-1,2)
cpp_sort_numeric_works(v)
cpp_sort_numeric_works(v, "DESC")
w <- v
w[1] <- -1
cpp_sort_numeric(v, w)
cpp_sort_numeric(v, w, "DESC")
*/
Output
> Rcpp::sourceCpp("~/git/stackoverflow/73222485/answer.cpp")
> v <- c(1,2,3,2,1,0,-1,2)
> cpp_sort_numeric_works(v)
[1] -1 0 1 1 2 2 2 3
> cpp_sort_numeric_works(v, "DESC")
[1] 3 2 2 2 1 1 0 -1
> w <- v
> w[1] <- -1
> cpp_sort_numeric(v, w)
[1] -1 0 1 1 2 2 2 3
> cpp_sort_numeric(v, w, "DESC")
[1] 3 2 2 2 1 1 0 -1
>