我注意到来自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
有办法避免这种情况吗?谢谢你的帮助
gstyhher1#
如果你看一下(短)源文件,你会发现它使用了一个内部类IndexHash。如果原始顺序是最重要的,我想你可以自己写一个新的方便 Package 。它不会这么难:冒着浪费几个字节内存的风险,分配一个临时的逻辑向量,使用一个标准的hashmap并在传入的向量上循环。对于每个值,询问hashmap是否已经看到这个值,存储布尔答案。然后使用它来索引原始向量。很有可能这甚至在某个地方实现了。也可以看看Armadillo和Eigen的效用函数。
IndexHash
gpnt7bae2#
这就是我如何实现它的,沿着我在提出它时试图解决的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; }
zazmityj3#
这一个可能会帮助一些人-只适用于排序向量。
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; }
o4tp2gmn4#
您可以使用duplicated(_) == 0来重复数据,同时保持第一次出现的顺序:
duplicated(_) == 0
IntegerVector x = {6,6,1,5,5,1}; IntegerVector out = x[duplicated(x) == 0]; Rcout << out << std::endl;
4条答案
按热度按时间gstyhher1#
如果你看一下(短)源文件,你会发现它使用了一个内部类
IndexHash
。如果原始顺序是最重要的,我想你可以自己写一个新的方便 Package 。它不会这么难:冒着浪费几个字节内存的风险,分配一个临时的逻辑向量,使用一个标准的hashmap并在传入的向量上循环。对于每个值,询问hashmap是否已经看到这个值,存储布尔答案。然后使用它来索引原始向量。
很有可能这甚至在某个地方实现了。也可以看看Armadillo和Eigen的效用函数。
gpnt7bae2#
这就是我如何实现它的,沿着我在提出它时试图解决的issue(使用this answer,它还显示了各种其他解决方案和基准测试)。
zazmityj3#
这一个可能会帮助一些人-只适用于排序向量。
o4tp2gmn4#
您可以使用
duplicated(_) == 0
来重复数据,同时保持第一次出现的顺序: