【问题标题】:Rcpp unique order outputrcpp 唯一订单输出
【发布时间】:2020-01-13 04:56:42
【问题描述】:

我注意到来自 Rcpp 的独特功能对结果进行排序

evalCpp("unique(IntegerVector::create(6,6,1,5,5,1))")
[1] 6 5 1
unique(c(6,6,1,5,5,1))
[1] 6 1 5

有没有办法避免这种情况? 感谢您的帮助

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    如果您查看(短)源文件,您会发现它使用了一个内部类IndexHash。我怀疑这是默认排序的。

    如果原始订单是最重要的,我想您可以为自己编写一个新的便利包装器。不可能这么难:冒着浪费几个字节内存的风险,分配一个临时逻辑向量,使用标准哈希图并遍历传入的向量。对于每个值,询问 hashmap 是否已经看到这个值,存储布尔答案。然后用它来索引原始向量。

    这甚至可能在某处实现。另请查看 Armadillo 和 Eigen 的实用函数。

    【讨论】:

    • 感谢您提供这些详细信息。实际上,我意识到在我的情况下,最简单的方法是在 Rcpp 程序中调用 R 唯一函数!
    【解决方案2】:

    这可能对某人有所帮助 - 仅适用于已排序的向量。

      template <int ITYPE>
      Rcpp::Vector<ITYPE> unique(Rcpp::Vector<ITYPE> x) {
        int n = x.size();
        if (n == 1) return(x);
    
        Rcpp::Vector<ITYPE> res;
        res.push_back(x(0));
    
    
        for (int i = 1; i < n; i++) {
          if (x[i] != x(i - 1)) {
            res.push_back(x(i));
          } 
        }
    
        return res;
      }
    
    
    

    【讨论】:

    • 这对于未排序的向量会失败。如果您添加对排序的调用,它将使该算法的复杂度次优。
    【解决方案3】:

    这就是我实现它的方式,以及我想出它时试图解决的issue(使用this answer,它还显示了各种其他解决方案和基准)。

      template < typename T, int RTYPE >
      inline SEXP sexp_unique( Rcpp::Vector< RTYPE > x ) {
        std::set< T > seen;
        auto newEnd = std::remove_if( x.begin(), x.end(), [&seen]( const T value ) {
          if ( seen.find( value ) != std::end( seen ) ) {
            return true;
          }
          seen.insert( value );
          return false;
        });
        x.erase( newEnd, x.end() );
        return x;
      }
    
    
      // returns unique values in their original input order
      inline SEXP get_sexp_unique( SEXP s ) {
    
        SEXP s2 = Rcpp::clone( s );
    
        switch( TYPEOF( s2 ) ) {
        case LGLSXP: {
          return sexp_unique< bool, LGLSXP >( s2 );
        }
        case REALSXP: {
          return sexp_unique< double, REALSXP >( s2 );
        }
        case INTSXP: {
          return sexp_unique< int, INTSXP >( s2 );
        }
        case STRSXP: {
          return sexp_unique< char* , STRSXP >( s2 );
        }
        default: Rcpp::stop("unknown vector type");
        }
        return 0;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-01
      • 1970-01-01
      • 2023-03-24
      • 2015-09-04
      • 1970-01-01
      相关资源
      最近更新 更多