[R] How to convert a C vector to an SEXP for using it in R_orderVector()?

Marius Hofert marius.hofert at uwaterloo.ca
Mon Mar 2 02:58:03 CET 2015


Inside a C function (foo()), I need to call R's order(). Writing R
Extensions (2014, Section 6.10) gave me the hint to use
R_orderVector() for this task. The third argument of this function
needs an SEXP containing (in my case) the vector x (of which I would
like to determine order()).

My question is: How can I convert the given C vector to an SEXP
acceptable by R_orderVector() [or, if there is an even more efficient
way to call a sort of order() from within C?]?

Here is how my setup roughly looks like: x and y are numeric(n) (but C
vectors obviously). The function should sort x oppositely to y. In R I
can simply do sort(x)[rev(rank(y))] (I wish everything was as easy as
in R...). The problem is: This function is called a million times and
a profiling revealed that 98% of the time is spend there... that's why
I'm looking for a C version (and also to see who much faster the C
version is *and* also to finally go to the dark side and learn a bit
of C again). Here is what my C code looks like so far:

double *foo(double *x, double *y, int n) {
    int *indx = malloc(n * sizeof(int)); /* R's order(); will contain
the order (permutation of 0:(n-1)) */
    R_orderVector(indx, n, Rf_lang1(*x), /* convert x to SEXP: HOW? */
                  TRUE, /* nalast (use same default as order()) */
                  TRUE); /* decreasing */
    /* => indx == rev(rank(y)) */
    R_rsort(x, n); /* R's sort(x) for real x */
    double *res = malloc(n * sizeof(double));
    for(int i=0; i<n; i++) res[i] = x[indx[i]];
    return res;

What I get is:
error: incompatible type for argument 1 of ‘Rf_lang1’

It's been a while since I programmed in C... the above function should
(run time wise) be efficient. If you see any room for improvement, I'd
be more than happy to hear about it.

Thanks & cheers,

More information about the R-help mailing list