Fast function to add vector elements by their names

performance, r, rcpp, vector

Solution

I would use something like this:

#include <Rcpp.h>
using namespace Rcpp; 

// [[Rcpp::export]]
NumericVector add_all(List vectors){
    RCPP_UNORDERED_MAP<std::string,double> out ; 
    int n = vectors.size() ;
    for( int i=0; i<n; i++){
        NumericVector x = vectors[i] ;
        CharacterVector names = x.attr("names") ;
        int m = x.size() ;

        for( int j=0; j<m; j++){
            String name = names[j] ;
            out[ name ] += x[j] ;   
        }
    }
    return wrap(out) ;
}

with the following wrapper:

add_vectors_cpp <- function(...){
    add_all( list(...) )
}

`RCPP_UNORDERED_MAP` being just a typedef to `unordered_map`, either in `std::` or in `std::tr1::` depending on your compiler, etc ...

The trick here is to create a regular list out of the `...` using the classic `list(...)`.

If you really wanted to pass down directly `...` in C++ and deal with it internally, you would have to use the `.External` interface. This is very rarely use, so Rcpp attributes don't support the `.External` interface.

With `.External`, it would look like this (untested):

SEXP add_vectors(SEXP args){
    RCPP_UNORDERED_MAP<std::string,double> out ; 
    args = CDR(args) ;
    while( args != R_NilValue ){
        NumericVector x = CAR(args) ;

        CharacterVector names = x.attr("names") ;
        int m = x.size() ;

        for( int j=0; j<m; j++){
            String name = names[j] ;
            out[ name ] += x[j] ;   
        }        
        args = CDR(args) ;
    }   
    return wrap(out) ;
}

Problem

I wrote this `R` function that, given any number of vectors (`...`) combines them by summing the respective element values ​​based on their names. ``` add_vectors <- function(...) { a <- list(...) nms <- sort(unique(unlist(lapply(a, names)))) out <- numeric(length(nms)) names(out) <- nms for (v in a) out[names(v)] <- out[names(v)] + v out } ``` Example: ``` v1 <- c(a=2,b=3,e=4) v2 <- c(b=1,c=6,d=0,a=4) add_vectors(v1, v2) # a b c d e 6 4 6 0 4 ``` I'm trying to write an equivalent function which is much faster. Unfortunately at the moment I have no idea how to achieve this in `R` so I thought to `Rcpp`. But, in order to convert in `Rcpp` this function I miss some concepts: - How to manage the `...` parameter. With a parameter of `List` type in `Rcpp` ? - How to iterate the vectors in the `...` parameter. - How to access (and then sum) the elements of the vectors by their name (this is very trivial in `R`, but I cannot figure how to do in `Rcpp`). So I'm looking for someone that can help me to improve the performances of this function (in `R` or `Rcpp`, or both). Any help is appreciated, thanks.

Original source