In einem Datensatz mit mehreren Beobachtungen für jedes Subjekt möchte ich eine Teilmenge mit nur dem maximalen Datenwert für jeden Datensatz erstellen. Zum Beispiel mit einem folgenden Datensatz:
ID <- c(1,1,1,2,2,2,2,3,3)
Value <- c(2,3,5,2,5,8,17,3,5)
Event <- c(1,1,2,1,2,1,2,2,2)
group <- data.frame(Subject=ID, pt=Value, Event=Event)
Subjekt 1, 2 und 3 haben den größten pt-Wert von 5, 17 bzw. 5.
Wie könnte ich zuerst den größten pt-Wert für jedes Subjekt finden und diese Beobachtung dann in einen anderen Datenrahmen einfügen? Der resultierende Datenrahmen sollte nur die größten pt-Werte für jedes Subjekt haben.
Antworten:
Hier ist eine
data.table
Lösung:Wenn Sie alle Einträge behalten möchten, die den Maximalwerten
pt
jeder Gruppe entsprechen:Wenn Sie nur den ersten Maximalwert von möchten
pt
:In diesem Fall macht es keinen Unterschied, da Ihre Daten in keiner Gruppe mehrere Maximalwerte enthalten.
quelle
.SD
Die Optimierung für diese Fälle steht noch auf der Liste. Behalte # 735 im Auge .?`.I`
ob die Erklärungen und Beispiele dort helfen?Die intuitivste Methode ist die Verwendung der Funktionen group_by und top_n in dplyr
Das Ergebnis ist
quelle
group %>% group_by(Subject) %>% arrange(desc(pt), .by_group = TRUE) %>% summarise(max_pt=first(pt), min_pt=last(pt), Event=first(Event))
slice(which.max(pt))
diese Option, um nur eine Zeile pro Gruppe einzuschließen.Eine kürzere Lösung mit
data.table
:quelle
group[group[, .I[which.max(pt)], by=Subject]$V1]
oben von @Arun vorgeschlagen. siehe Vergleiche hier.I
VersionEine andere Option ist
slice
quelle
which.max()
, so eine nützliche Funktion!Eine
dplyr
Lösung:Dies ergibt den folgenden Datenrahmen:
quelle
Event
Spalte in der Teilmenge behalten. In diesem Fall könnten Siedf %>% group_by(Subject) %>% filter(pt == max(pt))
Ich war mir nicht sicher, was Sie mit der Spalte "Ereignis" tun wollten, aber wenn Sie das auch beibehalten möchten, wie wäre es dann?
Hier sehen wir uns die
ave
Spalte "Wert" für jede "ID" an. Dann bestimmen wir, welcher Wert das Maximum ist, und wandeln diesen in einen logischen Vektor um, mit dem wir den ursprünglichen Datenrahmen unterteilen können.quelle
with
weil es etwas seltsam ist, die Daten sowohl innerhalb als auch außerhalb desgroup
data.frame verfügbar zu haben . Wenn Sie die Daten mitread.table
oder etwas einlesen , müssen Sie sie verwenden,with
da diese Spaltennamen außerhalb des data.frame nicht verfügbar sind.Base verwenden
R
quelle
Eine andere Basislösung
Ordnen Sie den Datenrahmen nach
pt
(absteigend) und entfernen Sie die darin duplizierten ZeilenSubject
quelle
Noch eine Base R-Lösung:
quelle
Hier ist eine andere
data.table
Lösung, dawhich.max
sie nicht für Zeichen funktioniertquelle
Seit {dplyr} v1.0.0 (Mai 2020) gibt es die neue
slice_*
Syntax, die ersetzttop_n()
.Siehe auch https://dplyr.tidyverse.org/reference/slice.html .
Erstellt am 18.08.2018 durch das reprex-Paket (v0.3.0.9001)
Sitzungsinfoquelle
Eine weitere
data.table
Option:Oder eine andere (weniger lesbar, aber etwas schneller):
Timing-Code:
Timings:
quelle
Eine andere
data.table
Lösung:quelle
by
ist eine Version vontapply
für Datenrahmen:Es gibt ein Objekt der Klasse zurück,
by
also konvertieren wir es in einen Datenrahmen:quelle
In der Basis können Sie verwenden
ave
, ummax
pro Gruppe zu erhalten und dies mit zu vergleichenpt
und einen logischen Vektor zu erhalten, um die zu unterteilendata.frame
.Oder vergleichen Sie es bereits in der Funktion.
quelle
Base R - Schnell - einfach in jeder Funktion anwendbar
Im Gegensatz zu anderen Lösungen ist diese Lösung immer noch schnell, benötigt keine zusätzliche Bibliothek und kann problemlos mit Argumenten innerhalb einer Funktion verwendet werden (verwenden Sie dann group [[argument]], wobei argument zB Zeichen ist).
Erstes Maximum
Alles maximal
quelle
Wenn Sie den größten pt-Wert für ein Thema wünschen, können Sie einfach Folgendes verwenden:
quelle