Ich habe den folgenden Datenrahmen
x <- read.table(text = " id1 id2 val1 val2
1 a x 1 9
2 a x 2 4
3 a y 3 5
4 a y 4 9
5 b x 1 7
6 b y 4 4
7 b x 3 9
8 b y 2 8", header = TRUE)
Ich möchte den Mittelwert von val1 und val2 berechnen, gruppiert nach id1 und id2, und gleichzeitig die Anzahl der Zeilen für jede Kombination aus id1 und id2 zählen. Ich kann jede Berechnung separat durchführen:
# calculate mean
aggregate(. ~ id1 + id2, data = x, FUN = mean)
# count rows
aggregate(. ~ id1 + id2, data = x, FUN = length)
Um beide Berechnungen in einem Aufruf durchzuführen, habe ich es versucht
do.call("rbind", aggregate(. ~ id1 + id2, data = x, FUN = function(x) data.frame(m = mean(x), n = length(x))))
Ich erhalte jedoch eine verstümmelte Ausgabe zusammen mit einer Warnung:
# m n
# id1 1 2
# id2 1 1
# 1.5 2
# 2 2
# 3.5 2
# 3 2
# 6.5 2
# 8 2
# 7 2
# 6 2
# Warning message:
# In rbind(id1 = c(1L, 2L, 1L, 2L), id2 = c(1L, 1L, 2L, 2L), val1 = list( :
# number of columns of result is not a multiple of vector length (arg 1)
Ich könnte das Plyr-Paket verwenden, aber mein Datensatz ist ziemlich groß und Plyr ist sehr langsam (fast unbrauchbar), wenn die Größe des Datensatzes zunimmt.
Wie kann ich aggregate
oder andere Funktionen verwenden, um mehrere Berechnungen in einem Aufruf durchzuführen?
aggregate
in den Antworten erwähnten gibt es auchby
undtapply
.Antworten:
Sie können alles in einem Schritt erledigen und die richtige Kennzeichnung erhalten:
Dadurch wird ein Datenrahmen mit zwei ID-Spalten und zwei Matrixspalten erstellt:
Wie von @ lord.garbage unten ausgeführt, kann dies mithilfe von in einen Datenrahmen mit "einfachen" Spalten konvertiert werden
do.call(data.frame, ...)
Dies ist die Syntax für mehrere Variablen in der LHS:
quelle
d$val1[ , ""mn"]
Sie, die Struktur mit zu betrachtenstr
.agg <- aggregate(cbind(val1, val2) ~ id1 + id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x)))
mithilfe vonagg_df <- do.call(data.frame, agg)
. Siehe auch hier .Angesichts dessen in der Frage:
Dann könnten Sie in
data.table
(1.9.4+
) versuchen:Für Zeitvergleiche
aggregate
(in Frage und alle 3 anderen Antworten verwendet),data.table
um diesen Benchmark (dieagg
undagg.x
Fälle) zu sehen.quelle
Sie können eine
count
Spalte hinzufügen , mit aggregierensum
und dann verkleinern, um Folgendes zu erhaltenmean
:Es hat den Vorteil, dass Sie Ihre Spaltennamen beibehalten und eine einzelne
count
Spalte erstellen .quelle
Mit dem
dplyr
Paket können Sie dies erreichen, indem Sie verwendensummarise_all
. Mit dieser Zusammenfassungsfunktion können Sie andere Funktionen (in diesem Fallmean
undn()
) auf jede der nicht gruppierenden Spalten anwenden :was gibt:
Wenn Sie die Funktion (en) nicht auf alle nicht gruppierten Spalten anwenden möchten, geben Sie die Spalten an, auf die sie angewendet werden sollen, oder indem Sie die nicht gewünschten mit einem Minus ausschließen, indem Sie die
summarise_at()
Funktion verwenden:quelle
Vielleicht möchten Sie zusammenführen ?
quelle
Sie können das auch verwenden
plyr::each()
, um mehrere Funktionen einzuführen:quelle
Eine weitere
dplyr
Option istacross
Teil der aktuellen EntwicklerversionErgebnis
quelle