Vorbemerkungen : Diese Frage ist meist von pädagogischem Wert, die eigentliche Aufgabe ist abgeschlossen, auch wenn der Ansatz nicht ganz optimal ist. Meine Frage ist, ob der folgende Code für Geschwindigkeit optimiert und / oder eleganter implementiert werden kann. Vielleicht mit zusätzlichen Paketen, wie zB plyr oder reshape. Auf den tatsächlichen Daten ausgeführt dauert es ungefähr 140 Sekunden, viel höher als die simulierten Daten, da einige der ursprünglichen Zeilen nichts als NA enthalten und zusätzliche Überprüfungen durchgeführt werden müssen. Zum Vergleich werden die simulierten Daten in etwa 30 Sekunden verarbeitet.
Bedingungen : Der Datensatz enthält 360 Variablen, 30 mal den Satz von 12. Benennen wir sie als V1_1, V1_2 ... (erster Satz), V2_1, V2_2 ... (zweiter Satz) und so weiter. Jeder Satz von 12 Variablen enthält dichotome (ja / nein) Antworten, die in der Praxis einem Karrierestatus entsprechen. Zum Beispiel: Arbeit (Ja / Nein), Studium (Ja / Nein) usw., insgesamt 12 Status, 30 Mal wiederholt.
Task : Die Aufgabe besteht darin, jeden Satz von 12 dichotomen Variablen in eine einzige Variable mit 12 Antwortkategorien (z. B. Arbeit, Studium ...) umzuschreiben. Letztendlich sollten wir 30 Variablen mit jeweils 12 Antwortkategorien erhalten.
Daten : Ich kann den eigentlichen Datensatz nicht posten, aber hier ist eine gute simulierte Approximation:
%Vor%Meine Lösung :
%Vor%Alles in allem gibt es eine doppelte * Anwendungsfunktion, eine über die Liste, die andere über die Datenrahmenzeilen. Das macht es ein bisschen langsam. Irgendwelche Vorschläge? Danke im Voraus.
Ich mag @ Aruns Matrixmultiplikationsidee sehr. Interessanterweise könnten Sie, wenn Sie R gegen einige OpenBLAS-Bibliotheken kompilieren, parallel dazu arbeiten.
Allerdings wollte ich Ihnen eine andere, vielleicht langsamer als Matrix-Multiplikation, Lösung anbieten, die Ihr ursprüngliches Muster verwendet, aber viel schneller ist als Ihre Implementierung:
%Vor%Wenn Sie einen sehr großen Datenrahmen und viele Prozessoren haben, können Sie diese Operation mit:
in Betracht ziehen %Vor% Nachdem ich @Arun und @mnel gelesen habe, habe ich eine Menge darüber gelernt, wie man diese Funktion verbessern kann, indem man die Nötigung zu einem Array vermeidet, indem man die data.frame
by Spalte statt der Zeile verarbeitet. Ich will hier keine Antwort "stehlen"; OP sollte in Erwägung ziehen, das Kontrollkästchen auf @ mnels Antwort zu setzen.
Ich wollte jedoch eine Lösung teilen, die data.table
nicht verwendet, und vermeidet for
. Es ist jedoch immer noch langsamer als @ Mnels Lösung, wenn auch nur geringfügig.
Ich möchte auch hinzufügen, dass @ Aarons Ansatz, which
mit arr.ind=TRUE
zu verwenden, auch sehr schnell und elegant wäre, wenn mydata
als matrix
und nicht als data.frame
beginnen würde. Die Koerziation auf matrix
ist langsamer als der Rest der Funktion. Wenn die Geschwindigkeit ein Problem wäre, wäre es eine Überlegung wert, die Daten als Matrix zu lesen.
Hier ist ein Ansatz, der im Prinzip sofort ist. (system.time = 0.1 Sekunden)
se set
. Die columnMatch-Komponente hängt von Ihren Daten ab. Wenn sie jedoch alle 12 Spalten umfasst, funktioniert Folgendes.
Dies würde genauso gut funktionieren, indem Spalten mit Bezug auf das Original hinzugefügt werden.
Hinweis set
funktioniert auch auf data.frames
....
IIUC, Sie haben nur ein 1
pro 12 Spalten. Du hast den Rest mit Nullen oder Nullen. Wenn dies der Fall ist, kann die Operation durch diese Idee viel schneller durchgeführt werden.
Die Idee: Anstatt jede Zeile durchzugehen und nach der Position von 1
zu fragen, könnten Sie eine Matrix mit den Dimensionen 1500 * 12
verwenden, wobei jede Zeile nur 1:12
ist. Das ist:
Nun können Sie diese Matrix mit jeder Ihrer Untermenge data.frame
(von gleichen Dimensionen, 1500 * 12 hier) multiplizieren und sie nehmen ihre "rowSums" (die vektorisiert ist) mit na.rm = TRUE
. Dies gibt dir direkt die Zeile, in der du 1 hast (weil diese 1 mit dem entsprechenden Wert zwischen 1 und 12 multipliziert wurde).
data.table-Implementierung: Hier werde ich data.table
verwenden, um die Idee zu veranschaulichen. Da es Spalte für Referenzen erstellt, würde ich erwarten, dass dieselbe Idee, die für data.frame
verwendet wird, ein bisschen langsamer ist, obwohl es Ihren aktuellen Code drastisch beschleunigen sollte.
Nun haben Sie 30 Spalten, die der Position von 1 entsprechen. Auf meinem System dauert dies etwa 0,4 Sekunden.
%Vor%Tags und Links optimization r apply