Ordne einen Datenrahmen spaltenweise in Rcpp an

8

Gibt es eine einfache Möglichkeit, einen DataFrame mit zwei (oder mehr oder einer) seiner Spalten in RCpp zu bestellen?

Es gibt viele Sortieralgorithmen im Netz, oder ich kann std::sort mit einem Wrapper für Dataframe verwenden, aber ich habe mich gefragt, ob in RCpp oder RCppArmadillo bereits etwas verfügbar ist?

Ich muss das Sortieren / Ordnen als Teil einer anderen Funktion machen

%Vor%

Ich möchte vermeiden, auf die Funktion order von R in RCpp zuzugreifen (um die Geschwindigkeit des RCpp-Codes zu erhalten).

Vielen Dank

    
uday 31.05.2014, 03:39
quelle

2 Antworten

11

Die Schwierigkeit besteht darin, dass ein Datenrahmen eine Menge von Vektoren ist, die möglicherweise verschiedene Typen haben; Wir brauchen eine Möglichkeit, sie unabhängig von diesen Typen zu sortieren (Ganzzahl, Zeichen, ...). In dplyr haben wir das entwickelt, was wir als Vektorbesucher bezeichnen. Für dieses spezielle Problem benötigen wir eine Menge von OrderVisitor , die die folgende Schnittstelle aufweist:

%Vor%

dplyr hat dann Implementierungen von OrderVisitor für alle unterstützten Typen in diesem Datei und wir haben eine Dispatcher-Funktion order_visitor , die ein OrderVisitor* aus einem Vektor macht.

Damit können wir eine Gruppe von Vektorbesuchern in einem std::vector<OrderVisitor*> speichern; Der OrderVisitors hat einen Konstruktor, der ein DataFrame und ein CharacterVector der Namen der Vektoren, die wir für die Bestellung verwenden möchten.

%Vor%

Dann können wir die Methode OrderVisitors.apply verwenden was im Wesentlichen lexikographische Ordnung macht:

%Vor%

Die apply -Methode wird implementiert, indem einfach ein IntegerVector mit 0..n und dann std::sort it entsprechend den Besuchern initialisiert wird.

%Vor%

Das Entscheidende hier ist, wie die Klasse OrderVisitors_Compare operator()(int,int) implementiert:

%Vor%

An diesem Punkt gibt index uns die ganzzahligen Indizes der sortierten Daten, wir müssen nur ein neues DataFrame von data machen, indem wir data mit diesen Indizes unterteilen. Dafür haben wir eine andere Art von Besuchern, eingekapselt in der Klasse DataFrameVisitors . Wir erstellen zuerst eine DataFrameVisitors :

%Vor%

Dies kapselt ein std::vector<VectorVisitor*> ein. Jeder dieser VectorVisitor* weiß, wie er sich selbst mit einem ganzzahligen Vektorindex untergliedert. Dies wird von DataFrameVisitors.subset verwendet:

%Vor%

Um dies zu vervollständigen, hier ist eine einfache Funktion mit Tools in dplyr entwickelt:

%Vor%     
Romain Francois 31.05.2014 11:39
quelle
3

Da eine data.frame in Wirklichkeit eine Liste von Spalten in C ++ ist, müssten Sie alle Ihre Spalten mit einem neuen Ordnungsindex neu ordnen. Dies unterscheidet sich von der Funktionsweise der [.., ..] Indizierung in R für data.frame .

Siehe z.B. dieser Rcpp Gallery Artikel zum Sortieren von Vektoren für einige Hinweise. Sie müssen wahrscheinlich den neuen zu verwendenden Bestellungsindex angeben, danach ist es nur eine Indizierungsfrage - und das hat auch einige Beiträge in der Galerie.

Dieser SO-Beitrag kann Sie bei der Indexerstellung unterstützen; Dieser Beitrag von bytes.com behandelt dieselbe Idee.

Bearbeiten: Und Armadillo hat Funktion sort_index() und stable_sort_index() zu Erstellen Sie den Index, den Sie für die Neuanordnung Ihrer Spalten benötigen. Dies deckt nur den Fall einer Spalte ab und ist auf numerische Spalten beschränkt, ist aber ein Anfang.

    
Dirk Eddelbuettel 31.05.2014 11:06
quelle

Tags und Links