【问题标题】:Intersect function with Rcpp与 Rcpp 相交函数
【发布时间】:2014-04-11 14:05:35
【问题描述】:

我很难用Rcpp 模块使用cppFunction 来实现一个功能。我需要使用类似 R 的 intersect 和两个 NumericVector 类型并返回另一个 NumericVector 的结果,就像在 R 中一样。

This 文档提供了一些帮助,但不幸的是,我几乎是 C++ atm 的菜鸟。

如何使用 cppFunction 实现 intersect R 函数?

谢谢

【问题讨论】:

    标签: c++ r rcpp


    【解决方案1】:

    您可能希望使用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
    

    【讨论】:

    • 不错。 FWIW 我们还有一个丑陋的大写宏给我们RCPP_UNORDERED_SET,无论编译器如何。但是通过插件询问更优雅:)
    • 啊,太好了! std::tr1::unordered_set 不适合我,所以很高兴知道 RCPP_UNORDERED_SET 存在。
    • 此外,还有糖功能,例如intersect 已经可用——但它以不同于Rintersect 的顺序返回输出。 (不过,您会得到相同的值)
    • push_back 正在扼杀它。每次使用时对所有数据进行深拷贝。永远不要在 Rcpp 向量上 push_back。仅供参考,push_back ...已从 Rcpp11 中删除。 @KevinUshey Sugar 的版本更糟糕。
    • @RomainFrancois 谢谢——我关注了Dirk's advice 并将其转换为std::vector&lt;double&gt;,但它似乎仍然比intersect 慢很多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多