Ich habe eine Liste von Mitarbeitern, und ich muss wissen, in welcher Abteilung sie sich am häufigsten befinden. Es ist trivial, die Mitarbeiter-ID anhand des Abteilungsnamens zu tabellieren, aber es ist schwieriger, den Abteilungsnamen und nicht die Anzahl der Dienstplanzählungen aus der Häufigkeitstabelle zurückzugeben. Ein einfaches Beispiel unten (Spaltennamen = Abteilungen, Zeilennamen = Mitarbeiter-IDs).
DF <- matrix(sample(1:9,9),ncol=3,nrow=3)
DF <- as.data.frame.matrix(DF)
> DF
V1 V2 V3
1 2 7 9
2 8 3 6
3 1 5 4
Wie komme ich jetzt?
> DF2
RE
1 V3
2 V1
3 V2
Antworten:
Eine Option, bei der Ihre Daten verwendet werden (zum späteren Nachschlagen verwenden Sie diese
set.seed()
, um Beispiele mithilfesample
reproduzierbarer Daten zu erstellen ):Eine schnellere Lösung als die Verwendung
apply
könnte seinmax.col
:... wo
ties.method
kann einer von"random"
"first"
oder sein"last"
Dies verursacht natürlich Probleme, wenn Sie zufällig zwei Spalten haben, die dem Maximum entsprechen. Ich bin nicht sicher, was Sie in diesem Fall tun möchten, da Sie für einige Zeilen mehr als ein Ergebnis haben. Z.B:
quelle
which.max
wird dann in Ordnung sein.apply
konvertiert dasdata.frame
inmatrix
intern. Möglicherweise sehen Sie bei diesen Dimensionen jedoch keinen Leistungsunterschied.colnames(DF)[max.col(replace(DF, cbind(seq_len(nrow(DF)), max.col(DF,ties.method="first")), -Inf), "first")]
Wenn Sie an einer
data.table
Lösung interessiert sind, finden Sie hier eine. Es ist etwas schwierig, da Sie es vorziehen, die ID für das erste Maximum zu erhalten. Es ist viel einfacher, wenn Sie lieber das letzte Maximum wollen. Trotzdem ist es nicht so kompliziert und schnell!Hier habe ich Daten Ihrer Dimensionen generiert (26746 * 18).
Daten
data.table
Antworten:Benchmarking:
Bei Daten dieser Dimensionen ist es ungefähr elfmal schneller und lässt sich auch
data.table
ziemlich gut skalieren.Bearbeiten: Wenn eine der maximalen IDs in Ordnung ist, dann:
quelle
Eine Lösung könnte darin bestehen, das Datum von breit auf lang umzustellen, alle Abteilungen in eine Spalte zu setzen und in einer anderen zu zählen, nach der Arbeitgeber-ID (in diesem Fall der Zeilennummer) zu gruppieren und dann mit dem zu den Abteilungen zu filtern Maximalwert. Es gibt auch einige Optionen für den Umgang mit Verbindungen mit diesem Ansatz.
quelle
Basierend auf den obigen Vorschlägen hat die folgende
data.table
Lösung für mich sehr schnell funktioniert:Und hat auch den Vorteil, dass Sie immer angeben können, welche Spalten
.SD
berücksichtigt werden sollen, indem Sie sie erwähnen in.SDcols
:Wenn wir den Spaltennamen des kleinsten Werts benötigen, wie von @lwshang vorgeschlagen, muss man nur Folgendes verwenden
-.SD
:quelle
which.min
in etwas zu verwenden, das aussehen würde:DT[, MIN := colnames(.SD)[apply(.SD,1,which.min)]]
oderDT[, MIN2 := colnames(.SD)[which.min(.SD)], by = 1:nrow(DT)]
auf den Dummy-Daten oben. Dies berücksichtigt keine Bindungen und gibt nur das erste Minimum zurück. Vielleicht sollten Sie eine separate Frage stellen. Ich wäre auch neugierig, welche anderen Antworten Sie bekommen würden.colnames(.SD)[max.col(-.SD, ties.method="first")]
.Eine
dplyr
Lösung:Idee:
Code:
Ergebnis:
Dieser Ansatz kann leicht erweitert werden, um die oberen
n
Spalten zu erhalten. Beispiel fürn=2
:Ergebnis:
quelle
Eine einfache
for
Schleife kann auch nützlich sein:quelle
Hier ist eine Antwort, die mit data.table funktioniert und einfacher ist. Dies setzt voraus, dass Ihre data.table den Namen hat
yourDF
:Ersetzen Sie
("V1", "V2", "V3", "V4")
und(V1, V2, V3, V4)
durch Ihre Spaltennamenquelle
Eine Option von
dplyr 1.0.0
könnte sein:Beispieldaten:
quelle