2014-04-11 95 views
1

我很難用Rcpp模塊使用cppFunction實現功能。我需要使用一些如R的intersect有兩個NumericVector類型,並用結果返回另一個NumericVector,就像R.與Rcpp相交功能

This文件已經有一定的幫助,但不幸的是,我幾乎在C++大氣壓一個小白。

我該如何實現intersect R函數cppFunction

感謝

回答

6

你可能會想使用類似unordered_set實施intersect

文件myintersect.cpp

#include <Rcpp.h> 
using namespace Rcpp; 

// Enable C++11 via this plugin (Rcpp 0.10.3 or later) 
// [[Rcpp::plugins(cpp11)]] 

// [[Rcpp::export]] 
NumericVector myintersect(NumericVector x, NumericVector y) { 
    std::vector<double> res; 
    std::unordered_set<double> s(y.begin(), y.end()); 
    for (int i=0; i < x.size(); ++i) { 
     auto f = s.find(x[i]); 
     if (f != s.end()) { 
      res.push_back(x[i]); 
      s.erase(f); 
     } 
    } 
    return Rcpp::wrap(res); 
} 

我們可以加載功能,並驗證它的工作原理:

library(Rcpp) 
sourceCpp(file="myintersect.cpp") 

set.seed(144) 
x <- c(-1, -1, sample(seq(1000000), 10000, replace=T)) 
y <- c(-1, sample(seq(1000000), 10000, replace=T)) 
all.equal(intersect(x, y), myintersect(x, y)) 
# [1] TRUE 

然而,看起來這種方法比itersect功能效率低很多:

library(microbenchmark) 
microbenchmark(intersect(x, y), myintersect(x, y)) 
# Unit: microseconds 
#    expr  min  lq median  uq  max neval 
# intersect(x, y) 424.167 495.861 501.919 523.7835 989.997 100 
# myintersect(x, y) 1778.609 1798.111 1808.575 1835.1570 2571.426 100 
+3

不錯。 FWIW我們也有一個醜陋的大寫宏給我們'RCPP_UNORDERED_SET',而不考慮編譯器。但通過插件詢問更優雅:) –

+0

好啊! 'std :: tr1 :: unordered_set'不適合我,所以很高興知道'RCPP_UNORDERED_SET'存在。 – josliber

+1

此外,還有糖的功能,例如, 'intersect'已經可用 - 但它返回的輸出順序不同於'R'的'intersect'。 (雖然你得到相同的值) –