在RCPP中,有没有任何简单的方法按数据帧的两个(或多个或一个)列对数据帧进行排序?
网络上有许多可用的排序算法,或者我可以使用
我需要将此排序/排序作为另一个函数的一部分
DataFrame myFunc(DataFrame myDF, NumericVector x) {
//// some code here
DataFrame myDFsorted = sort (myDF, someColName1, someColName2) // how to sort??
//// some code here
}
我希望避免访问RCpp中的R's
非常感谢
困难在于数据帧是一组可能具有不同类型的向量;我们需要一种方法来独立于这些类型(整数,字符,。。。。)对它们进行排序。在dplyr中,我们开发了我们所说的向量访问者。对于这个特定的问题,我们需要的是一组
class OrderVisitor {
public:
virtual ~OrderVisitor(){}
/** are the elements at indices i and j equal */
virtual bool equal(int i, int j) const = 0 ;
/** is the i element less than the j element */
virtual bool before( int i, int j) const = 0 ;
virtual SEXP get() = 0 ;
} ;
然后,dplyr为我们在此文件中支持的所有类型提供了
有了这个,我们可以将一组向量访问者存储到
OrderVisitors o(data, names ) ;
然后,我们可以使用
IntegerVector index = o.apply() ;
inline Rcpp::IntegerVector OrderVisitors::apply() const {
IntegerVector x = seq(0, nrows -1 ) ;
std::sort( x.begin(), x.end(), OrderVisitors_Compare(*this) ) ;
return x ;
}
这里的相关内容是
inline bool operator()(int i, int j) const {
if( i == j ) return false ;
for( int k=0; k<n; k++)
if( ! obj.visitors[k]->equal(i,j) )
return obj.visitors[k]->before(i, j ) ;
return i < j ;
}
因此,此时
DataFrameVisitors visitors( data ) ;
这封装了一个
template <typename Container>
DataFrame subset( const Container& index, const CharacterVector& classes ) const {
List out(nvisitors);
for( int k=0; k<nvisitors; k++){
out[k] = get(k)->subset(index) ;
}
structure( out, Rf_length(out[0]) , classes) ;
return (SEXP)out ;
}
为了总结这一点,下面是一个使用DPLYR中开发的工具的简单函数:
#include <dplyr.h>
// [[Rcpp::depends(dplyr)]]
using namespace Rcpp ;
using namespace dplyr ;
// [[Rcpp::export]]
DataFrame myFunc(DataFrame data, CharacterVector names) {
OrderVisitors o(data, names ) ;
IntegerVector index = o.apply() ;
DataFrameVisitors visitors( data ) ;
DataFrame res = visitors.subset(index, "data.frame" ) ;
return res ;
}
因为
例如,请参阅Rcpp画廊关于排序向量的文章,以获得一些指针。您可能必须提供要使用的新的排序索引,然后它只是一个索引问题--这也有一些帖子在画廊上。
这篇SO文章可能会让您开始创建索引;Bytes.com的这篇文章讨论了同样的想法。
编辑:Armadillo有